03 Oct 2009
This commit is contained in:
parent
aef0afadfc
commit
3ac2a6e3ec
|
@ -34,14 +34,15 @@ launch\imagelib\
|
|||
launch\extragen\
|
||||
physic\
|
||||
public\
|
||||
render\
|
||||
server\
|
||||
server\ents\
|
||||
server\game\
|
||||
server\global\
|
||||
server\monsters\
|
||||
vprogs\
|
||||
vsound\
|
||||
snd_al\
|
||||
snd_dx\
|
||||
vid_gl\
|
||||
xtools\
|
||||
xtools\bsplib
|
||||
xtools\ripper
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -410,7 +410,23 @@ int CHud :: MsgFunc_RoomType( const char *pszName, int iSize, void *pbuf )
|
|||
|
||||
int CHud :: MsgFunc_ScreenFade( const char *pszName, int iSize, void *pbuf )
|
||||
{
|
||||
// FIXME: implement
|
||||
BEGIN_READ( pszName, iSize, pbuf );
|
||||
|
||||
float fadeTime = READ_SHORT() / (1<<12);
|
||||
float holdTime = READ_SHORT() / (1<<12);
|
||||
int fadeFlags = READ_SHORT();
|
||||
|
||||
Vector m_FadeColor;
|
||||
|
||||
m_FadeColor.x = READ_BYTE(); // fade red
|
||||
m_FadeColor.y = READ_BYTE(); // fade green
|
||||
m_FadeColor.z = READ_BYTE(); // fade blue
|
||||
float alpha = READ_BYTE(); // fade alpha
|
||||
|
||||
SetScreenFade( m_FadeColor, alpha, fadeTime, holdTime, fadeFlags );
|
||||
|
||||
END_READ();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
12
debug.bat
12
debug.bat
|
@ -23,7 +23,7 @@ if errorlevel 1 set BUILD_ERROR=1
|
|||
%MSDEV% physic/physic.dsp %CONFIG%"physic - Win32 Debug" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% render/render.dsp %CONFIG%"render - Win32 Debug" %build_target%
|
||||
%MSDEV% vid_gl/vid_gl.dsp %CONFIG%"vid_gl - Win32 Debug" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% server/server.dsp %CONFIG%"server - Win32 Debug" %build_target%
|
||||
|
@ -32,7 +32,10 @@ if errorlevel 1 set BUILD_ERROR=1
|
|||
%MSDEV% vprogs/vprogs.dsp %CONFIG%"vprogs - Win32 Debug" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% vsound/vsound.dsp %CONFIG%"vsound - Win32 Debug" %build_target%
|
||||
%MSDEV% snd_al/snd_al.dsp %CONFIG%"snd_al - Win32 Debug" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% snd_dx/snd_dx.dsp %CONFIG%"snd_dx - Win32 Debug" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% xtools/xtools.dsp %CONFIG%"xtools - Win32 Debug" %build_target%
|
||||
|
@ -63,10 +66,11 @@ if exist engine\engine.plg del /f /q engine\engine.plg
|
|||
if exist launch\launch.plg del /f /q launch\launch.plg
|
||||
if exist physic\physic.plg del /f /q physic\physic.plg
|
||||
if exist server\server.plg del /f /q server\server.plg
|
||||
if exist render\render.plg del /f /q render\render.plg
|
||||
if exist vid_gl\vid_gl.plg del /f /q vid_gl\vid_gl.plg
|
||||
if exist viewer\viewer.plg del /f /q viewer\viewer.plg
|
||||
if exist vprogs\vprogs.plg del /f /q vprogs\vprogs.plg
|
||||
if exist vsound\vsound.plg del /f /q vsound\vsound.plg
|
||||
if exist snd_al\snd_al.plg del /f /q snd_al\snd_al.plg
|
||||
if exist snd_dx\snd_dx.plg del /f /q snd_dx\snd_dx.plg
|
||||
if exist xtools\xtools.plg del /f /q xtools\xtools.plg
|
||||
|
||||
echo Build succeeded!
|
||||
|
|
|
@ -31,6 +31,18 @@ edict_t *CL_GetEdictByIndex( int index )
|
|||
return EDICT_NUM( index );
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_GetServerTime
|
||||
|
||||
don't clamped time that come from server
|
||||
====================
|
||||
*/
|
||||
int CL_GetServerTime( void )
|
||||
{
|
||||
return cl.frame.servertime;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
StudioEvent
|
||||
|
|
|
@ -57,6 +57,10 @@ extern cvar_t *allow_download;
|
|||
//======================================================================
|
||||
|
||||
//======================================================================
|
||||
bool CL_CheckKeydest( void )
|
||||
{
|
||||
return (cls.key_dest != key_game);
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
@ -673,7 +677,8 @@ Call before entering a new level, or after changing dlls
|
|||
void CL_PrepSound( void )
|
||||
{
|
||||
int i, sndcount;
|
||||
|
||||
|
||||
MsgDev( D_LOAD, "CL_PrepSound: %s\n", cl.configstrings[CS_NAME] );
|
||||
for( i = 0, sndcount = 0; i < MAX_SOUNDS && cl.configstrings[CS_SOUNDS+i+1][0]; i++ )
|
||||
sndcount++; // total num sounds
|
||||
|
||||
|
@ -707,7 +712,7 @@ void CL_PrepVideo( void )
|
|||
return; // no map loaded
|
||||
|
||||
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
|
||||
MsgDev( D_LOAD, "CL_PrepRefresh: %s\n", cl.configstrings[CS_NAME] );
|
||||
MsgDev( D_LOAD, "CL_PrepVideo: %s\n", cl.configstrings[CS_NAME] );
|
||||
// let the render dll load the map
|
||||
FS_FileBase( cl.configstrings[CS_MODELS+1], mapname );
|
||||
re->BeginRegistration( mapname, pe->VisData()); // load map
|
||||
|
@ -1134,8 +1139,6 @@ void CL_InitLocal( void )
|
|||
Cmd_AddCommand ("download", CL_Download_f, "download specified resource (by name)" );
|
||||
|
||||
CL_InitServerCommands ();
|
||||
|
||||
UI_SetActiveMenu( UI_MAINMENU );
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -1163,6 +1166,8 @@ CL_Frame
|
|||
*/
|
||||
void CL_Frame( int time )
|
||||
{
|
||||
bool clear;
|
||||
|
||||
if( host.type == HOST_DEDICATED )
|
||||
return;
|
||||
|
||||
|
@ -1184,7 +1189,9 @@ void CL_Frame( int time )
|
|||
CL_SendCommand();
|
||||
|
||||
// predict all unacknowledged movements
|
||||
CL_PredictMovement ();
|
||||
CL_PredictMovement();
|
||||
|
||||
Host_CheckChanges();
|
||||
|
||||
// allow rendering DLL change
|
||||
if( cls.state == ca_active )
|
||||
|
@ -1198,8 +1205,10 @@ void CL_Frame( int time )
|
|||
|
||||
SCR_MakeScreenShot();
|
||||
|
||||
clear = (cls.state > ca_disconnected && cls.state < ca_active) ? true : false;
|
||||
|
||||
// update audio
|
||||
S_Update( cl.playernum + 1, cl.refdef.simorg, cl.refdef.simvel, cl.refdef.forward, cl.refdef.up );
|
||||
S_Update( cl.playernum + 1, cl.refdef.simorg, cl.refdef.simvel, cl.axis, clear );
|
||||
|
||||
// advance local effects for next frame
|
||||
CL_RunDLights ();
|
||||
|
@ -1228,15 +1237,14 @@ void CL_Init( void )
|
|||
cl_paused = Cvar_Get( "paused", "0", 0, "game paused" );
|
||||
|
||||
Con_Init();
|
||||
VID_Init();
|
||||
|
||||
if( !CL_LoadProgs( "client" ))
|
||||
Host_Error( "CL_InitGame: can't initialize client.dll\n" );
|
||||
|
||||
MSG_Init( &net_message, net_message_buffer, sizeof( net_message_buffer ));
|
||||
|
||||
UI_Init();
|
||||
SCR_Init();
|
||||
Host_CheckChanges ();
|
||||
|
||||
CL_InitLocal();
|
||||
cls.initialized = true;
|
||||
}
|
||||
|
|
|
@ -339,6 +339,9 @@ void CL_PredictMovement (void)
|
|||
|
||||
pmove = EDICT_NUM( cl.playernum + 1 )->pvClientData->current;
|
||||
|
||||
// unpredicted pure angled values converted into axis
|
||||
AngleVectors( cl.refdef.cl_viewangles, cl.axis[0], cl.axis[1], cl.axis[2] );
|
||||
|
||||
if( !cl_predict->value || cl.frame.ps.ed_flags & ESF_NO_PREDICTION )
|
||||
{
|
||||
// just set angles
|
||||
|
|
|
@ -20,6 +20,7 @@ cvar_t *cl_testflashlight;
|
|||
cvar_t *cl_levelshot_name;
|
||||
cvar_t *cl_envshot_size;
|
||||
cvar_t *cl_font;
|
||||
static bool scr_init = false;
|
||||
|
||||
void SCR_TimeRefresh_f( void );
|
||||
void SCR_Loading_f( void );
|
||||
|
@ -393,10 +394,10 @@ void SCR_MakeScreenShot( void )
|
|||
switch( cls.scrshot_action )
|
||||
{
|
||||
case scrshot_plaque:
|
||||
re->ScrShot( cls.shotname, VID_LEVELSHOT );
|
||||
if( re ) re->ScrShot( cls.shotname, VID_LEVELSHOT );
|
||||
break;
|
||||
case scrshot_savegame:
|
||||
re->ScrShot( cls.shotname, VID_SAVESHOT );
|
||||
if( re ) re->ScrShot( cls.shotname, VID_SAVESHOT );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -465,6 +466,12 @@ SCR_Init
|
|||
*/
|
||||
void SCR_Init( void )
|
||||
{
|
||||
if( scr_init ) return;
|
||||
|
||||
// must be init before startup video subsystem
|
||||
scr_width = Cvar_Get( "width", "640", 0, "screen width" );
|
||||
scr_height = Cvar_Get( "height", "480", 0, "screen height" );
|
||||
|
||||
scr_showpause = Cvar_Get( "scr_showpause", "1", 0, "show pause picture" );
|
||||
scr_centertime = Cvar_Get( "scr_centertime", "2.5", 0, "centerprint hold time" );
|
||||
scr_printspeed = Cvar_Get( "scr_printspeed", "8", 0, "centerprint speed of print" );
|
||||
|
@ -485,8 +492,23 @@ void SCR_Init( void )
|
|||
Cmd_AddCommand( "viewpos", SCR_Viewpos_f, "prints current player origin" );
|
||||
|
||||
SCR_RegisterShaders();
|
||||
UI_Init();
|
||||
|
||||
if( cls.state == ca_disconnected )
|
||||
UI_SetActiveMenu( UI_MAINMENU );
|
||||
scr_init = true;
|
||||
}
|
||||
|
||||
void SCR_Shutdown( void )
|
||||
{
|
||||
if( !scr_init ) return;
|
||||
|
||||
Cmd_RemoveCommand( "timerefresh" );
|
||||
Cmd_RemoveCommand( "loading" );
|
||||
Cmd_RemoveCommand( "skyname" );
|
||||
Cmd_RemoveCommand( "setfont" );
|
||||
Cmd_RemoveCommand( "viewpos" );
|
||||
|
||||
UI_Shutdown();
|
||||
scr_init = false;
|
||||
}
|
|
@ -118,6 +118,7 @@ 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;
|
||||
|
@ -450,6 +451,7 @@ bool CL_LoadProgs( const char *name );
|
|||
void CL_ParseUserMessage( sizebuf_t *msg, int svc_num );
|
||||
void CL_LinkUserMessage( char *pszName, const int svc_num );
|
||||
void CL_SortUserMessages( void );
|
||||
int CL_GetServerTime( void );
|
||||
float CL_GetLerpFrac( void );
|
||||
edict_t *CL_AllocEdict( void );
|
||||
void CL_InitEdict( edict_t *pEdict );
|
||||
|
@ -507,7 +509,6 @@ void CL_Download_f( void );
|
|||
//
|
||||
void SCR_Init( void );
|
||||
void SCR_UpdateScreen( void );
|
||||
void VID_Init( void );
|
||||
void SCR_Shutdown( void );
|
||||
void SCR_RegisterShaders( void );
|
||||
void SCR_AdjustSize( float *x, float *y, float *w, float *h );
|
||||
|
|
|
@ -121,6 +121,7 @@ int Host_CompareFileTime( long ft1, long ft2 );
|
|||
void Host_AbortCurrentFrame( void );
|
||||
void Host_WriteDefaultConfig( void );
|
||||
void Host_WriteConfig( void );
|
||||
void Host_CheckChanges( void );
|
||||
int Host_Milliseconds( void );
|
||||
void Host_Print( const char *txt );
|
||||
void Host_Error( const char *error, ... );
|
||||
|
@ -351,6 +352,7 @@ void CL_MouseEvent( int mx, int my );
|
|||
void CL_AddLoopingSounds( void );
|
||||
void CL_RegisterSounds( void );
|
||||
void CL_Drop( void );
|
||||
bool CL_CheckKeydest( void );
|
||||
char *Info_ValueForKey( char *s, char *key );
|
||||
void Info_RemoveKey( char *s, char *key );
|
||||
void Info_SetValueForKey( char *s, char *key, char *value );
|
||||
|
|
|
@ -87,9 +87,6 @@ void Con_ToggleConsole_f( void )
|
|||
{
|
||||
UI_SetActiveMenu( UI_CLOSEMENU );
|
||||
cls.key_dest = key_console;
|
||||
|
||||
if( com.atoi(cl.configstrings[CS_MAXCLIENTS]) == 1 && Host_ServerState())
|
||||
Cvar_SetValue( "paused", 1 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -659,7 +656,6 @@ void Con_Close( void )
|
|||
Con_ClearNotify();
|
||||
con.finalFrac = 0; // none visible
|
||||
con.displayFrac = 0;
|
||||
Cvar_SetValue( "paused", 0 );
|
||||
}
|
||||
|
||||
bool Con_Active( void )
|
||||
|
|
|
@ -132,18 +132,18 @@ void IN_ActivateMouse( void )
|
|||
width = GetSystemMetrics(SM_CXSCREEN);
|
||||
height = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
GetWindowRect( host.hWnd, &window_rect);
|
||||
if (window_rect.left < 0) window_rect.left = 0;
|
||||
if (window_rect.top < 0) window_rect.top = 0;
|
||||
if (window_rect.right >= width) window_rect.right = width - 1;
|
||||
if (window_rect.bottom >= height-1) window_rect.bottom = height - 1;
|
||||
GetWindowRect( host.hWnd, &window_rect );
|
||||
if( window_rect.left < 0 ) window_rect.left = 0;
|
||||
if( window_rect.top < 0 ) window_rect.top = 0;
|
||||
if( window_rect.right >= width ) window_rect.right = width - 1;
|
||||
if( window_rect.bottom >= height - 1 ) window_rect.bottom = height - 1;
|
||||
|
||||
window_center_x = (window_rect.right + window_rect.left)/2;
|
||||
window_center_y = (window_rect.top + window_rect.bottom)/2;
|
||||
window_center_x = (window_rect.right + window_rect.left) / 2;
|
||||
window_center_y = (window_rect.top + window_rect.bottom) / 2;
|
||||
SetCursorPos( window_center_x, window_center_y );
|
||||
|
||||
SetCapture( host.hWnd );
|
||||
ClipCursor(&window_rect);
|
||||
ClipCursor( &window_rect );
|
||||
while( ShowCursor(false) >= 0 );
|
||||
}
|
||||
|
||||
|
@ -349,16 +349,16 @@ long IN_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam )
|
|||
RECT r;
|
||||
int xPos, yPos, style;
|
||||
|
||||
xPos = (short) LOWORD(lParam); // horizontal position
|
||||
yPos = (short) HIWORD(lParam); // vertical position
|
||||
xPos = (short)LOWORD( lParam ); // horizontal position
|
||||
yPos = (short)HIWORD( lParam ); // vertical position
|
||||
|
||||
r.left = r.top = 0;
|
||||
r.right = r.bottom = 1;
|
||||
style = GetWindowLong( hWnd, GWL_STYLE );
|
||||
AdjustWindowRect( &r, style, FALSE );
|
||||
|
||||
Cvar_SetValue( "r_xpos", xPos + r.left);
|
||||
Cvar_SetValue( "r_ypos", yPos + r.top);
|
||||
Cvar_SetValue( "r_xpos", xPos + r.left );
|
||||
Cvar_SetValue( "r_ypos", yPos + r.top );
|
||||
scr_xpos->modified = false;
|
||||
scr_ypos->modified = false;
|
||||
}
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: engine - Win32 Debug--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1F65.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_parse.c"
|
||||
]
|
||||
Creating command line "cl.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1F65.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1F66.tmp" with contents
|
||||
[
|
||||
user32.lib msvcrtd.lib /nologo /subsystem:windows /dll /incremental:yes /pdb:"..\temp\engine\!debug/engine.pdb" /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"..\temp\engine\!debug/engine.dll" /implib:"..\temp\engine\!debug/engine.lib" /pdbtype:sept
|
||||
"\Xash3D\src_main\temp\engine\!debug\cinematic.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_cmds.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_demo.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_effects.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_frame.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_game.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_input.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_main.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_parse.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_phys.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_scrn.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\cl_view.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\com_library.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\con_keys.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\con_main.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\con_utils.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\engfuncs.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\engine.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\host.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\infostring.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\input.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\net_chan.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\net_huff.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\net_msg.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_client.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_cmds.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_frame.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_game.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_init.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_main.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_move.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_phys.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_save.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\sv_world.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_advanced.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_audio.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_controls.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_credits.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_defaults.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_demos.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_gameoptions.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_gotosite.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_ingame.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_loadgame.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_main.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_menu.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_mods.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_multiplayer.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_network.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_options.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_performance.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_playersetup.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_qmenu.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_quit.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_savegame.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_singleplayer.obj"
|
||||
"\Xash3D\src_main\temp\engine\!debug\ui_video.obj"
|
||||
]
|
||||
Creating command line "link.exe @C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1F66.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1F67.bat" with contents
|
||||
[
|
||||
@echo off
|
||||
copy \Xash3D\src_main\temp\engine\!debug\engine.dll "D:\Xash3D\bin\engine.dll"
|
||||
]
|
||||
Creating command line "C:\DOCUME~1\MIKE~1.MIK\LOCALS~1\Temp\RSP1F67.bat"
|
||||
Compiling...
|
||||
cl_parse.c
|
||||
Linking...
|
||||
<h3>Output Window</h3>
|
||||
Performing Custom Build Step on \Xash3D\src_main\temp\engine\!debug\engine.dll
|
||||
‘Ş®Ż¨ŕ®˘ ® ä ©«®˘: 1.
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
engine.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
289
engine/host.c
289
engine/host.c
|
@ -7,6 +7,8 @@
|
|||
#include "input.h"
|
||||
#include "client.h"
|
||||
|
||||
#define MAX_RENDERS 8
|
||||
|
||||
physic_exp_t *pe;
|
||||
render_exp_t *re;
|
||||
vprogs_exp_t *vm;
|
||||
|
@ -14,13 +16,17 @@ vsound_exp_t *se;
|
|||
host_parm_t host; // host parms
|
||||
stdlib_api_t com, newcom;
|
||||
|
||||
byte *zonepool;
|
||||
char *buildstring = __TIME__ " " __DATE__;
|
||||
byte *zonepool;
|
||||
char *buildstring = __TIME__ " " __DATE__;
|
||||
string video_dlls[MAX_RENDERS];
|
||||
string audio_dlls[MAX_RENDERS];
|
||||
int num_audio_dlls;
|
||||
int num_video_dlls;
|
||||
|
||||
dll_info_t render_dll = { "", NULL, "CreateAPI", NULL, NULL, 0, sizeof(render_exp_t), sizeof(stdlib_api_t) };
|
||||
dll_info_t vsound_dll = { "", NULL, "CreateAPI", NULL, NULL, 0, sizeof(vsound_exp_t), sizeof(stdlib_api_t) };
|
||||
dll_info_t physic_dll = { "physic.dll", NULL, "CreateAPI", NULL, NULL, 1, sizeof(physic_exp_t), sizeof(stdlib_api_t) };
|
||||
dll_info_t render_dll = { "render.dll", NULL, "CreateAPI", NULL, NULL, 0, sizeof(render_exp_t), sizeof(stdlib_api_t) };
|
||||
dll_info_t vprogs_dll = { "vprogs.dll", NULL, "CreateAPI", NULL, NULL, 1, sizeof(vprogs_exp_t), sizeof(stdlib_api_t) };
|
||||
dll_info_t vsound_dll = { "vsound.dll", NULL, "CreateAPI", NULL, NULL, 0, sizeof(vsound_exp_t), sizeof(stdlib_api_t) };
|
||||
|
||||
cvar_t *timescale;
|
||||
cvar_t *host_serverstate;
|
||||
|
@ -29,6 +35,8 @@ cvar_t *host_maxfps;
|
|||
cvar_t *host_minfps;
|
||||
cvar_t *host_framerate;
|
||||
cvar_t *host_registered;
|
||||
cvar_t *host_audio;
|
||||
cvar_t *host_video;
|
||||
|
||||
// these cvars will be duplicated on each client across network
|
||||
int Host_ServerState( void ) { return Cvar_VariableInteger( "host_serverstate" ); }
|
||||
|
@ -58,7 +66,7 @@ void Host_InitPhysic( void )
|
|||
pi.ClientMove = SV_PlayerMove;
|
||||
pi.GetModelVerts = SV_GetModelVerts;
|
||||
|
||||
Sys_LoadLibrary( &physic_dll );
|
||||
Sys_LoadLibrary( NULL, &physic_dll );
|
||||
|
||||
CreatePhysic = (void *)physic_dll.main;
|
||||
pe = CreatePhysic( &newcom, &pi );
|
||||
|
@ -76,54 +84,11 @@ void Host_FreePhysic( void )
|
|||
Sys_FreeLibrary( &physic_dll );
|
||||
}
|
||||
|
||||
void Host_InitRender( void )
|
||||
{
|
||||
static render_imp_t ri;
|
||||
launch_t CreateRender;
|
||||
bool result = false;
|
||||
|
||||
ri.api_size = sizeof(render_imp_t);
|
||||
|
||||
// studio callbacks
|
||||
ri.UpdateScreen = SCR_UpdateScreen;
|
||||
ri.StudioEvent = CL_StudioEvent;
|
||||
ri.StudioFxTransform = CL_StudioFxTransform;
|
||||
ri.ShowCollision = pe->DrawCollision;
|
||||
ri.GetClientEdict = CL_GetEdictByIndex;
|
||||
ri.GetLocalPlayer = CL_GetLocalPlayer;
|
||||
ri.GetMaxClients = CL_GetMaxClients;
|
||||
ri.GetLerpFrac = CL_GetLerpFrac;
|
||||
ri.WndProc = IN_WndProc;
|
||||
|
||||
Sys_LoadLibrary( &render_dll );
|
||||
|
||||
if( render_dll.link )
|
||||
{
|
||||
CreateRender = (void *)render_dll.main;
|
||||
re = CreateRender( &newcom, &ri );
|
||||
|
||||
if( re->Init( true )) result = true;
|
||||
}
|
||||
|
||||
// video system not started, run dedicated server
|
||||
if( !result ) Sys_NewInstance( va("#%s", GI->gamedir ), "Host_InitRender: fallback to dedicated mode\n" );
|
||||
}
|
||||
|
||||
void Host_FreeRender( void )
|
||||
{
|
||||
if( render_dll.link )
|
||||
{
|
||||
re->Shutdown( true );
|
||||
Mem_Set( &re, 0, sizeof( re ));
|
||||
}
|
||||
Sys_FreeLibrary( &render_dll );
|
||||
}
|
||||
|
||||
void Host_InitVprogs( const int argc, const char **argv )
|
||||
{
|
||||
launch_t CreateVprogs;
|
||||
|
||||
Sys_LoadLibrary( &vprogs_dll );
|
||||
Sys_LoadLibrary( NULL, &vprogs_dll );
|
||||
|
||||
CreateVprogs = (void *)vprogs_dll.main;
|
||||
vm = CreateVprogs( &newcom, NULL ); // second interface not allowed
|
||||
|
@ -136,11 +101,57 @@ void Host_FreeVprogs( void )
|
|||
if( vprogs_dll.link )
|
||||
{
|
||||
vm->Free();
|
||||
Mem_Set( &vm, 0, sizeof(vm));
|
||||
Mem_Set( &vm, 0, sizeof( vm ));
|
||||
}
|
||||
Sys_FreeLibrary( &vprogs_dll );
|
||||
}
|
||||
|
||||
void Host_FreeRender( void )
|
||||
{
|
||||
if( render_dll.link )
|
||||
{
|
||||
SCR_Shutdown ();
|
||||
re->Shutdown( true );
|
||||
Mem_Set( &re, 0, sizeof( re ));
|
||||
}
|
||||
Sys_FreeLibrary( &render_dll );
|
||||
}
|
||||
|
||||
bool Host_InitRender( void )
|
||||
{
|
||||
static render_imp_t ri;
|
||||
launch_t CreateRender;
|
||||
bool result = false;
|
||||
|
||||
ri.api_size = sizeof( render_imp_t );
|
||||
|
||||
// studio callbacks
|
||||
ri.UpdateScreen = SCR_UpdateScreen;
|
||||
ri.StudioEvent = CL_StudioEvent;
|
||||
ri.StudioFxTransform = CL_StudioFxTransform;
|
||||
ri.ShowCollision = pe->DrawCollision;
|
||||
ri.GetClientEdict = CL_GetEdictByIndex;
|
||||
ri.GetLocalPlayer = CL_GetLocalPlayer;
|
||||
ri.GetMaxClients = CL_GetMaxClients;
|
||||
ri.GetLerpFrac = CL_GetLerpFrac;
|
||||
ri.WndProc = IN_WndProc;
|
||||
|
||||
Sys_LoadLibrary( host_video->string, &render_dll );
|
||||
|
||||
if( render_dll.link )
|
||||
{
|
||||
CreateRender = (void *)render_dll.main;
|
||||
re = CreateRender( &newcom, &ri );
|
||||
|
||||
if( re->Init( true )) result = true;
|
||||
}
|
||||
|
||||
// video system not started, shutdown refresh subsystem
|
||||
if( !result ) Host_FreeRender();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Host_FreeSound( void )
|
||||
{
|
||||
if( vsound_dll.link )
|
||||
|
@ -151,19 +162,20 @@ void Host_FreeSound( void )
|
|||
Sys_FreeLibrary( &vsound_dll );
|
||||
}
|
||||
|
||||
void Host_InitSound( void )
|
||||
bool Host_InitSound( void )
|
||||
{
|
||||
static vsound_imp_t si;
|
||||
launch_t CreateSound;
|
||||
bool result = false;
|
||||
static vsound_imp_t si;
|
||||
launch_t CreateSound;
|
||||
bool result = false;
|
||||
|
||||
// phys callback
|
||||
si.api_size = sizeof(vsound_imp_t);
|
||||
si.api_size = sizeof( vsound_imp_t );
|
||||
si.GetSoundSpatialization = CL_GetEntitySoundSpatialization;
|
||||
si.PointContents = CL_PointContents;
|
||||
si.AddLoopingSounds = CL_AddLoopingSounds;
|
||||
si.GetServerTime = CL_GetServerTime;
|
||||
|
||||
Sys_LoadLibrary( &vsound_dll );
|
||||
Sys_LoadLibrary( host_audio->string, &vsound_dll );
|
||||
|
||||
if( vsound_dll.link )
|
||||
{
|
||||
|
@ -175,6 +187,68 @@ void Host_InitSound( void )
|
|||
|
||||
// audio system not started, shutdown sound subsystem
|
||||
if( !result ) Host_FreeSound();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Host_CheckChanges( void )
|
||||
{
|
||||
int num_changes;
|
||||
|
||||
if( host_video->modified || host_audio->modified )
|
||||
{
|
||||
host.state = HOST_RESTART;
|
||||
S_StopAllSounds(); // don't let them loop during the restart
|
||||
|
||||
if( host_video->modified ) cl.video_prepped = false;
|
||||
if( host_audio->modified ) cl.audio_prepped = false;
|
||||
}
|
||||
else return;
|
||||
|
||||
num_changes = 0;
|
||||
|
||||
// restart or change renderer
|
||||
while( host_video->modified )
|
||||
{
|
||||
host_video->modified = false;
|
||||
|
||||
Host_FreeRender(); // release render.dll
|
||||
if( !Host_InitRender( )) // load it again
|
||||
{
|
||||
if( num_changes > num_video_dlls )
|
||||
{
|
||||
Sys_NewInstance( va("#%s", GI->gamefolder ), "fallback to dedicated mode\n" );
|
||||
return;
|
||||
}
|
||||
if( !com.strcmp( video_dlls[num_changes], host_video->string ))
|
||||
num_changes++; // already trying - failed
|
||||
Cvar_FullSet( "host_video", video_dlls[num_changes], CVAR_SYSTEMINFO );
|
||||
num_changes++;
|
||||
}
|
||||
else SCR_Init ();
|
||||
}
|
||||
|
||||
num_changes = 0;
|
||||
|
||||
// restart or change sound engine
|
||||
while( host_audio->modified )
|
||||
{
|
||||
host_audio->modified = false;
|
||||
|
||||
Host_FreeSound(); // release sound.dll
|
||||
if( !Host_InitSound( )) // load it again
|
||||
{
|
||||
if( num_changes > num_audio_dlls )
|
||||
{
|
||||
MsgDev( D_ERROR, "couldn't initialize sound system\n" );
|
||||
return;
|
||||
}
|
||||
if( !com.strcmp( audio_dlls[num_changes], host_audio->string ))
|
||||
num_changes++; // already trying - failed
|
||||
Cvar_FullSet( "host_audio", audio_dlls[num_changes], CVAR_SYSTEMINFO );
|
||||
num_changes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -208,14 +282,7 @@ Restart the video subsystem
|
|||
*/
|
||||
void Host_VidRestart_f( void )
|
||||
{
|
||||
host.state = HOST_RESTART;
|
||||
S_StopAllSounds(); // don't let them loop during the restart
|
||||
cl.video_prepped = false;
|
||||
|
||||
Host_FreeRender(); // release render.dll
|
||||
Host_InitRender(); // load it again
|
||||
|
||||
SCR_RegisterShaders(); // reload 2d-shaders
|
||||
host_video->modified = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -227,12 +294,7 @@ Restart the audio subsystem
|
|||
*/
|
||||
void Host_SndRestart_f( void )
|
||||
{
|
||||
host.state = HOST_RESTART;
|
||||
S_StopAllSounds(); // don't let them loop during the restart
|
||||
cl.audio_prepped = false;
|
||||
|
||||
Host_FreeSound(); // release vsound.dll
|
||||
Host_InitSound(); // load it again
|
||||
host_audio->modified = true;
|
||||
}
|
||||
|
||||
void Host_ChangeGame_f( void )
|
||||
|
@ -263,25 +325,6 @@ void Host_Minimize_f( void )
|
|||
if( host.hWnd ) ShowWindow( host.hWnd, SW_MINIMIZE );
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
VID_Init
|
||||
============
|
||||
*/
|
||||
void VID_Init( void )
|
||||
{
|
||||
scr_width = Cvar_Get( "width", "640", 0, "screen width" );
|
||||
scr_height = Cvar_Get( "height", "480", 0, "screen height" );
|
||||
|
||||
Cmd_AddCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
|
||||
Cmd_AddCommand( "vid_restart", Host_VidRestart_f, "restarts video system" );
|
||||
Cmd_AddCommand( "snd_restart", Host_SndRestart_f, "restarts audio system" );
|
||||
Cmd_AddCommand( "game", Host_ChangeGame_f, "change game" );
|
||||
|
||||
Host_InitRender();
|
||||
Host_InitSound();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_InitEvents
|
||||
|
@ -429,7 +472,9 @@ int Host_ModifyTime( int msec )
|
|||
{
|
||||
// clients of remote servers do not want to clamp time, because
|
||||
// it would skew their view of the server's time temporarily
|
||||
clamp_time = 5000;
|
||||
if( cls.state == ca_cinematic )
|
||||
clamp_time = (1000 / host_maxfps->integer);
|
||||
else clamp_time = 5000;
|
||||
}
|
||||
|
||||
if( msec > clamp_time ) msec = clamp_time;
|
||||
|
@ -467,6 +512,9 @@ void Host_Frame( void )
|
|||
last_time = host.frametime[0];
|
||||
time = Host_ModifyTime( time );
|
||||
|
||||
if( host.state == HOST_RESTART )
|
||||
host.state = HOST_FRAME;
|
||||
|
||||
SV_Frame ( time ); // server frame
|
||||
CL_Frame ( time ); // client frame
|
||||
VM_Frame ( time ); // vprogs frame
|
||||
|
@ -559,14 +607,17 @@ void Host_Error_f( void )
|
|||
Host_Crash_f
|
||||
=================
|
||||
*/
|
||||
static void Host_Crash_f (void)
|
||||
static void Host_Crash_f( void )
|
||||
{
|
||||
*(int *)0 = 0xffffffff;
|
||||
}
|
||||
|
||||
void Host_InitCommon( const int argc, const char **argv )
|
||||
{
|
||||
char dev_level[4];
|
||||
char dev_level[4];
|
||||
dll_info_t check_vid, check_snd;
|
||||
search_t *dlls;
|
||||
int i;
|
||||
|
||||
newcom = com;
|
||||
|
||||
|
@ -584,6 +635,52 @@ void Host_InitCommon( const int argc, const char **argv )
|
|||
zonepool = Mem_AllocPool( "Zone Engine" );
|
||||
|
||||
IN_Init();
|
||||
|
||||
// initialize audio\video multi-dlls system
|
||||
num_video_dlls = num_audio_dlls = 0;
|
||||
host_video = Cvar_Get( "host_video", "vid_gl.dll", CVAR_SYSTEMINFO, "name of video rendering library" );
|
||||
host_audio = Cvar_Get( "host_audio", "snd_al.dll", CVAR_SYSTEMINFO, "name of sound rendering library" );
|
||||
|
||||
// make sure what global copy has no changed with any dll checking
|
||||
Mem_Copy( &check_vid, &render_dll, sizeof( dll_info_t ));
|
||||
Mem_Copy( &check_snd, &vsound_dll, sizeof( dll_info_t ));
|
||||
|
||||
// checking dlls don't invoke crash!
|
||||
check_vid.crash = false;
|
||||
check_snd.crash = false;
|
||||
|
||||
dlls = FS_Search( "*.dll", true );
|
||||
|
||||
// couldn't find any dlls, render is missing (but i'm don't know how laucnher find engine :)
|
||||
// probably this should never happen
|
||||
if( !dlls ) Sys_NewInstance( "©", "" );
|
||||
|
||||
for( i = 0; i < dlls->numfilenames; i++ )
|
||||
{
|
||||
if(!com.strnicmp( "vid_", dlls->filenames[i], 4 ))
|
||||
{
|
||||
// make sure what found library is valid
|
||||
if( Sys_LoadLibrary( dlls->filenames[i], &check_vid ))
|
||||
{
|
||||
MsgDev( D_NOTE, "VideoLibrary[%i]: %s\n", num_video_dlls, dlls->filenames[i] );
|
||||
com.strncpy( video_dlls[num_video_dlls], dlls->filenames[i], MAX_STRING );
|
||||
Sys_FreeLibrary( &check_vid );
|
||||
num_video_dlls++;
|
||||
}
|
||||
}
|
||||
else if(!com.strnicmp( "snd_", dlls->filenames[i], 4 ))
|
||||
{
|
||||
// make sure what found library is valid
|
||||
if( Sys_LoadLibrary( dlls->filenames[i], &check_snd ))
|
||||
{
|
||||
MsgDev( D_NOTE, "AudioLibrary[%i]: %s\n", num_audio_dlls, dlls->filenames[i] );
|
||||
com.strncpy( audio_dlls[num_audio_dlls], dlls->filenames[i], MAX_STRING );
|
||||
Sys_FreeLibrary( &check_snd );
|
||||
num_audio_dlls++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Mem_Free( dlls );
|
||||
}
|
||||
|
||||
void Host_FreeCommon( void )
|
||||
|
@ -645,6 +742,14 @@ void Host_Init( const int argc, const char **argv )
|
|||
Cmd_AddCommand( "quit", Sys_Quit, "quit the game" );
|
||||
Cmd_AddCommand( "exit", Sys_Quit, "quit the game" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Cmd_AddCommand( "minimize", Host_Minimize_f, "minimize main window to tray" );
|
||||
Cmd_AddCommand( "vid_restart", Host_VidRestart_f, "restarts video system" );
|
||||
Cmd_AddCommand( "snd_restart", Host_SndRestart_f, "restarts audio system" );
|
||||
}
|
||||
|
||||
Cmd_AddCommand( "game", Host_ChangeGame_f, "change game" ); // allow to change game from the console
|
||||
host.frametime[0] = Host_Milliseconds();
|
||||
host.errorframe = 0;
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ void SV_Map_f( void )
|
|||
else spawn_entity = GI->sp_entity;
|
||||
|
||||
com.strncpy( filename, Cmd_Argv( 1 ), sizeof( filename ));
|
||||
if( !SV_MapIsValid( filename, spawn_entity ))
|
||||
if( !SV_MapIsValid( filename, spawn_entity ) && host.developer <= 1 )
|
||||
{
|
||||
Msg( "SV_NewMap: invalid map %s\n", filename );
|
||||
return;
|
||||
|
|
|
@ -2329,6 +2329,8 @@ pfnIndexOfEdict
|
|||
*/
|
||||
int pfnIndexOfEdict( const edict_t *pEdict )
|
||||
{
|
||||
if( !pEdict || pEdict->free )
|
||||
return 0;
|
||||
return NUM_FOR_EDICT( pEdict );
|
||||
}
|
||||
|
||||
|
|
|
@ -252,6 +252,8 @@ void SV_SpawnServer( const char *server, const char *startspot )
|
|||
|
||||
Msg( "SpawnServer [^2%s^7]\n", server );
|
||||
|
||||
Cmd_ExecuteString( "latch\n" );
|
||||
|
||||
if( sv.state == ss_dead && !sv.loadgame )
|
||||
SV_InitGame(); // the game is just starting
|
||||
|
||||
|
@ -354,8 +356,6 @@ void SV_InitGame( void )
|
|||
}
|
||||
|
||||
MsgDev( D_INFO, "Dll loaded for mod %s\n", svgame.dllFuncs.pfnGetGameDescription() );
|
||||
|
||||
Cmd_ExecuteString( "latch\n" );
|
||||
svs.initialized = true;
|
||||
|
||||
if( Cvar_VariableValue( "coop" ) && Cvar_VariableValue ( "deathmatch" ) && Cvar_VariableValue( "teamplay" ))
|
||||
|
|
|
@ -241,9 +241,6 @@ bool SV_CheckPaused( void )
|
|||
int i, count;
|
||||
sv_client_t *cl;
|
||||
|
||||
if( !sv_paused->integer )
|
||||
return false;
|
||||
|
||||
// only pause if there is just a single client connected
|
||||
for( i = count = 0, cl = svs.clients; i < sv_maxclients->integer; i++, cl++ )
|
||||
{
|
||||
|
@ -259,6 +256,12 @@ bool SV_CheckPaused( void )
|
|||
return false;
|
||||
}
|
||||
|
||||
if( CL_CheckKeydest() )
|
||||
return true;
|
||||
|
||||
if( !sv_paused->integer )
|
||||
return false;
|
||||
|
||||
if( !sv_paused->integer )
|
||||
Cvar_Set( "paused", "1" );
|
||||
return true;
|
||||
|
|
|
@ -323,7 +323,7 @@ static void UI_Video_UpdateConfig( void )
|
|||
}
|
||||
|
||||
uiVideo.glExtensions.generic.name = uiVideoYesNo[(int)uiVideo.glExtensions.curValue];
|
||||
uiVideo.videoMode.generic.name = uiVideoModes[(int)uiVideo.videoMode.curValue + 1];
|
||||
uiVideo.videoMode.generic.name = uiVideoModes[(int)uiVideo.videoMode.curValue];
|
||||
uiVideo.fullScreen.generic.name = uiVideoYesNo[(int)uiVideo.fullScreen.curValue];
|
||||
uiVideo.colorDepth.generic.name = uiVideoBits[(int)uiVideo.colorDepth.curValue];
|
||||
uiVideo.hardwareGamma.generic.name = uiVideoYesNo[(int)uiVideo.hardwareGamma.curValue];
|
||||
|
|
121
launch/cmd.c
121
launch/cmd.c
|
@ -45,17 +45,17 @@ Cbuf_AddText
|
|||
Adds command text at the end of the buffer
|
||||
============
|
||||
*/
|
||||
void Cbuf_AddText(const char *text)
|
||||
void Cbuf_AddText( const char *text )
|
||||
{
|
||||
int l;
|
||||
|
||||
l = com_strlen(text);
|
||||
if (cmd_text.cursize + l >= cmd_text.maxsize)
|
||||
l = com.strlen( text );
|
||||
if( cmd_text.cursize + l >= cmd_text.maxsize )
|
||||
{
|
||||
MsgDev(D_WARN, "Cbuf_AddText: overflow\n");
|
||||
MsgDev( D_WARN, "Cbuf_AddText: overflow\n" );
|
||||
return;
|
||||
}
|
||||
Mem_Copy(&cmd_text.data[cmd_text.cursize], (char *)text, l);
|
||||
Mem_Copy( &cmd_text.data[cmd_text.cursize], text, l );
|
||||
cmd_text.cursize += l;
|
||||
}
|
||||
|
||||
|
@ -73,22 +73,22 @@ void Cbuf_InsertText (const char *text)
|
|||
{
|
||||
int i, len;
|
||||
|
||||
len = strlen( text ) + 1;
|
||||
if ( len + cmd_text.cursize > cmd_text.maxsize )
|
||||
len = com.strlen( text ) + 1;
|
||||
if( len + cmd_text.cursize > cmd_text.maxsize )
|
||||
{
|
||||
MsgDev(D_WARN,"Cbuf_InsertText overflowed\n" );
|
||||
MsgDev( D_WARN, "Cbuf_InsertText overflowed\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// move the existing command text
|
||||
for ( i = cmd_text.cursize - 1; i >= 0; i-- )
|
||||
for( i = cmd_text.cursize - 1; i >= 0; i-- )
|
||||
{
|
||||
cmd_text.data[i + len] = cmd_text.data[i];
|
||||
}
|
||||
|
||||
// copy the new text in
|
||||
Mem_Copy( cmd_text.data, (char *)text, len - 1 );
|
||||
cmd_text.data[ len - 1 ] = '\n'; // add a \n
|
||||
cmd_text.data[len - 1] = '\n'; // add a \n
|
||||
cmd_text.cursize += len;
|
||||
}
|
||||
|
||||
|
@ -97,23 +97,23 @@ void Cbuf_InsertText (const char *text)
|
|||
Cbuf_ExecuteText
|
||||
============
|
||||
*/
|
||||
void Cbuf_ExecuteText (int exec_when, const char *text)
|
||||
void Cbuf_ExecuteText( int exec_when, const char *text )
|
||||
{
|
||||
switch (exec_when)
|
||||
switch( exec_when )
|
||||
{
|
||||
case EXEC_NOW:
|
||||
if (text && strlen(text))
|
||||
Cmd_ExecuteString(text);
|
||||
if( text && com.strlen( text ))
|
||||
Cmd_ExecuteString( text );
|
||||
else Cbuf_Execute();
|
||||
break;
|
||||
case EXEC_INSERT:
|
||||
Cbuf_InsertText (text);
|
||||
Cbuf_InsertText( text );
|
||||
break;
|
||||
case EXEC_APPEND:
|
||||
Cbuf_AddText (text);
|
||||
Cbuf_AddText( text );
|
||||
break;
|
||||
default:
|
||||
MsgDev( D_ERROR, "Cbuf_ExecuteText: bad execute target\n");
|
||||
MsgDev( D_ERROR, "Cbuf_ExecuteText: bad execute target\n" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -143,28 +143,33 @@ void Cbuf_Execute( void )
|
|||
text = (char *)cmd_text.data;
|
||||
|
||||
quotes = 0;
|
||||
for (i = 0; i < cmd_text.cursize; i++)
|
||||
for( i = 0; i < cmd_text.cursize; i++ )
|
||||
{
|
||||
if (text[i] == '"') quotes++;
|
||||
if ( !(quotes&1) && text[i] == ';')
|
||||
if( text[i] == '"') quotes++;
|
||||
if(!( quotes & 1 ) && text[i] == ';' )
|
||||
break; // don't break if inside a quoted string
|
||||
if (text[i] == '\n' || text[i] == '\r' ) break;
|
||||
if( text[i] == '\n' || text[i] == '\r' ) break;
|
||||
}
|
||||
|
||||
if( i >= (MAX_CMD_LINE - 1)) i = MAX_CMD_LINE - 1;
|
||||
Mem_Copy (line, text, i);
|
||||
if( i >= MAX_CMD_LINE - 1 )
|
||||
Sys_Error( "Cbuf_Execute: command string owerflow\n" );
|
||||
|
||||
Mem_Copy( line, text, i );
|
||||
line[i] = 0;
|
||||
|
||||
|
||||
// delete the text from the command buffer and move remaining commands down
|
||||
// this is necessary because commands (exec) can insert data at the
|
||||
// beginning of the text buffer
|
||||
|
||||
if (i == cmd_text.cursize) cmd_text.cursize = 0;
|
||||
if( i == cmd_text.cursize )
|
||||
{
|
||||
cmd_text.cursize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
cmd_text.cursize -= i;
|
||||
memmove (text, text+i, cmd_text.cursize);
|
||||
memmove( text, text + i, cmd_text.cursize );
|
||||
}
|
||||
|
||||
// execute the command line
|
||||
|
@ -195,7 +200,7 @@ void Cmd_StuffCmds_f( void )
|
|||
|
||||
if(Cmd_Argc() != 1)
|
||||
{
|
||||
Msg("stuffcmds : execute command line parameters\n");
|
||||
Msg( "stuffcmds : execute command line parameters\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -261,26 +266,27 @@ void Cmd_Exec_f (void)
|
|||
{
|
||||
string rcpath;
|
||||
size_t len;
|
||||
|
||||
char *f;
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "exec <filename> : execute a script file\n" );
|
||||
Msg( "Usage: exec <filename>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
com.snprintf( rcpath, MAX_STRING, "config/%s", Cmd_Argv(1));
|
||||
com.snprintf( rcpath, MAX_STRING, "config/%s", Cmd_Argv( 1 ));
|
||||
FS_DefaultExtension( rcpath, ".rc" ); // append as default
|
||||
|
||||
f = FS_LoadFile(rcpath, &len );
|
||||
if (!f)
|
||||
if( !f )
|
||||
{
|
||||
MsgDev( D_WARN, "couldn't exec %s\n", Cmd_Argv(1));
|
||||
MsgDev( D_WARN, "couldn't exec %s\n", Cmd_Argv( 1 ));
|
||||
return;
|
||||
}
|
||||
MsgDev(D_INFO, "execing %s\n",Cmd_Argv(1));
|
||||
Cbuf_InsertText(f);
|
||||
Mem_Free(f);
|
||||
|
||||
MsgDev( D_INFO, "execing %s\n", Cmd_Argv( 1 ));
|
||||
Cbuf_InsertText( f );
|
||||
Mem_Free( f );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -331,10 +337,10 @@ typedef struct cmd_function_s
|
|||
xcommand_t function;
|
||||
} cmd_function_t;
|
||||
|
||||
static int cmd_argc;
|
||||
static char *cmd_argv[MAX_STRING_TOKENS];
|
||||
static char cmd_tokenized[MAX_MSGLEN+MAX_STRING_TOKENS]; // will have 0 bytes inserted
|
||||
static cmd_function_t *cmd_functions; // possible commands to execute
|
||||
static int cmd_argc;
|
||||
static char *cmd_argv[MAX_STRING_TOKENS];
|
||||
static char cmd_tokenized[MAX_CMD_BUFFER]; // will have 0 bytes inserted
|
||||
static cmd_function_t *cmd_functions; // possible commands to execute
|
||||
|
||||
/*
|
||||
============
|
||||
|
@ -390,7 +396,7 @@ are inserted in the apropriate place, The argv array
|
|||
will point into this temporary buffer.
|
||||
============
|
||||
*/
|
||||
void Cmd_TokenizeString (const char *text_in)
|
||||
void Cmd_TokenizeString( const char *text_in )
|
||||
{
|
||||
const char *text;
|
||||
char *textOut;
|
||||
|
@ -404,36 +410,37 @@ void Cmd_TokenizeString (const char *text_in)
|
|||
while( 1 )
|
||||
{
|
||||
// this is usually something malicious
|
||||
if ( cmd_argc == MAX_STRING_TOKENS ) return;
|
||||
if( cmd_argc == MAX_STRING_TOKENS ) return;
|
||||
|
||||
while ( 1 )
|
||||
while( 1 )
|
||||
{
|
||||
// skip whitespace
|
||||
while ( *text && *text <= ' ' ) text++;
|
||||
if ( !*text ) return; // all tokens parsed
|
||||
while( *text && *text <= ' ' ) text++;
|
||||
if( !*text ) return; // all tokens parsed
|
||||
|
||||
// skip // comments
|
||||
if ( text[0] == '/' && text[1] == '/' ) return; // all tokens parsed
|
||||
if( text[0] == '/' && text[1] == '/' ) return; // all tokens parsed
|
||||
|
||||
// skip /* */ comments
|
||||
if ( text[0] == '/' && text[1] =='*' )
|
||||
if( text[0] == '/' && text[1] =='*' )
|
||||
{
|
||||
while(*text && ( text[0] != '*' || text[1] != '/' )) text++;
|
||||
if ( !*text ) return; // all tokens parsed
|
||||
while( *text && ( text[0] != '*' || text[1] != '/' )) text++;
|
||||
if( !*text ) return; // all tokens parsed
|
||||
text += 2;
|
||||
}
|
||||
else break; // we are ready to parse a token
|
||||
}
|
||||
|
||||
// handle quoted strings
|
||||
if ( *text == '"' )
|
||||
if( *text == '"' )
|
||||
{
|
||||
cmd_argv[cmd_argc] = textOut;
|
||||
cmd_argc++;
|
||||
text++;
|
||||
while ( *text && *text != '"' ) *textOut++ = *text++;
|
||||
while( *text && *text != '"' )
|
||||
*textOut++ = *text++;
|
||||
*textOut++ = 0;
|
||||
if ( !*text ) return; // all tokens parsed
|
||||
if( !*text ) return; // all tokens parsed
|
||||
text++;
|
||||
continue;
|
||||
}
|
||||
|
@ -443,12 +450,12 @@ void Cmd_TokenizeString (const char *text_in)
|
|||
cmd_argc++;
|
||||
|
||||
// skip until whitespace, quote, or command
|
||||
while ( *text > ' ' )
|
||||
while( *text > ' ' )
|
||||
{
|
||||
if ( text[0] == '"' ) break;
|
||||
if ( text[0] == '/' && text[1] == '/' ) break;
|
||||
if( text[0] == '"' ) break;
|
||||
if( text[0] == '/' && text[1] == '/' ) break;
|
||||
// skip /* */ comments
|
||||
if ( text[0] == '/' && text[1] =='*' ) break;
|
||||
if( text[0] == '/' && text[1] =='*' ) break;
|
||||
|
||||
*textOut++ = *text++;
|
||||
}
|
||||
|
@ -464,7 +471,7 @@ void Cmd_TokenizeString (const char *text_in)
|
|||
Cmd_AddCommand
|
||||
============
|
||||
*/
|
||||
void Cmd_AddCommand (const char *cmd_name, xcommand_t function, const char *cmd_desc)
|
||||
void Cmd_AddCommand( const char *cmd_name, xcommand_t function, const char *cmd_desc )
|
||||
{
|
||||
cmd_function_t *cmd;
|
||||
|
||||
|
@ -559,7 +566,7 @@ void Cmd_ExecuteString( const char *text )
|
|||
if( !Cmd_Argc()) return; // no tokens
|
||||
|
||||
// check registered command functions
|
||||
for ( prev = &cmd_functions; *prev; prev = &cmd->next )
|
||||
for( prev = &cmd_functions; *prev; prev = &cmd->next )
|
||||
{
|
||||
cmd = *prev;
|
||||
if(!com.stricmp( cmd_argv[0], cmd->name ))
|
||||
|
|
|
@ -301,7 +301,7 @@ cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
|
|||
MsgDev(D_INFO, "%s is system variable.\n", var_name);
|
||||
return var;
|
||||
}
|
||||
if( var->flags & (CVAR_LATCH|CVAR_LATCH_VIDEO))
|
||||
if( var->flags & (CVAR_LATCH|CVAR_LATCH_VIDEO|CVAR_LATCH_AUDIO))
|
||||
{
|
||||
if( var->latched_string )
|
||||
{
|
||||
|
@ -315,26 +315,29 @@ cvar_t *Cvar_Set2 (const char *var_name, const char *value, bool force)
|
|||
return var;
|
||||
}
|
||||
|
||||
if( Cvar_VariableInteger( "host_serverstate" ))
|
||||
if( var->flags & CVAR_LATCH && Cvar_VariableInteger( "host_serverstate" ))
|
||||
{
|
||||
MsgDev( D_INFO, "%s will be changed upon restarting.\n", var->name );
|
||||
var->latched_string = copystring( value );
|
||||
}
|
||||
else if( var->flags & CVAR_LATCH_VIDEO )
|
||||
{
|
||||
MsgDev( D_INFO, "%s will be changed upon restarting video.\n", var->name );
|
||||
var->latched_string = copystring( value );
|
||||
}
|
||||
else if( var->flags & CVAR_LATCH_AUDIO )
|
||||
{
|
||||
MsgDev( D_INFO, "%s will be changed upon restarting audio.\n", var->name );
|
||||
var->latched_string = copystring( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( var->flags & CVAR_LATCH_VIDEO )
|
||||
{
|
||||
MsgDev( D_INFO, "%s will be changed upon restarting video.\n", var->name );
|
||||
var->latched_string = copystring( value );
|
||||
}
|
||||
else
|
||||
{
|
||||
Mem_Free( var->string ); // free the old value string
|
||||
var->string = copystring( value );
|
||||
var->value = com.atof( var->string );
|
||||
var->integer = com.atoi( var->string );
|
||||
}
|
||||
Mem_Free( var->string ); // free the old value string
|
||||
var->string = copystring( value );
|
||||
var->value = com.atof( var->string );
|
||||
var->integer = com.atoi( var->string );
|
||||
}
|
||||
|
||||
var->modified = true;
|
||||
var->modificationCount++;
|
||||
return var;
|
||||
|
@ -684,28 +687,31 @@ void Cvar_List_f( void )
|
|||
if( match && !com_stricmpext( match, var->name ))
|
||||
continue;
|
||||
|
||||
if( var->flags & CVAR_SERVERINFO ) Msg( "S" );
|
||||
if( var->flags & CVAR_SERVERINFO ) Msg( "SV " );
|
||||
else Msg( " " );
|
||||
|
||||
if( var->flags & CVAR_USERINFO ) Msg( "U" );
|
||||
if( var->flags & CVAR_USERINFO ) Msg( "USER " );
|
||||
else Msg( " " );
|
||||
|
||||
if( var->flags & CVAR_READ_ONLY ) Msg( "R" );
|
||||
if( var->flags & CVAR_READ_ONLY ) Msg( "READ " );
|
||||
else Msg( " " );
|
||||
|
||||
if( var->flags & CVAR_INIT ) Msg( "I" );
|
||||
if( var->flags & CVAR_INIT ) Msg( "INIT " );
|
||||
else Msg( " " );
|
||||
|
||||
if( var->flags & CVAR_ARCHIVE ) Msg( "A" );
|
||||
if( var->flags & CVAR_ARCHIVE ) Msg( "ARCH " );
|
||||
else Msg( " " );
|
||||
|
||||
if( var->flags & CVAR_LATCH ) Msg( "L" );
|
||||
if( var->flags & CVAR_LATCH ) Msg( "LATCH" );
|
||||
else Msg( " " );
|
||||
|
||||
if( var->flags & CVAR_LATCH_VIDEO ) Msg( "V" );
|
||||
if( var->flags & CVAR_LATCH_VIDEO ) Msg( "VIDEO" );
|
||||
else Msg( " " );
|
||||
|
||||
if( var->flags & CVAR_CHEAT ) Msg( "C" );
|
||||
if( var->flags & CVAR_LATCH_AUDIO ) Msg( "AUDIO" );
|
||||
else Msg( " " );
|
||||
|
||||
if( var->flags & CVAR_CHEAT ) Msg( "CHEAT" );
|
||||
else Msg( " " );
|
||||
Msg(" %s \"%s\"\n", var->name, var->string );
|
||||
j++;
|
||||
|
@ -820,6 +826,35 @@ void Cvar_LatchedVideo_f( void )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Latched_f
|
||||
|
||||
Now all latched audio strings is valid
|
||||
============
|
||||
*/
|
||||
void Cvar_LatchedAudio_f( void )
|
||||
{
|
||||
cvar_t *var;
|
||||
cvar_t **prev;
|
||||
|
||||
prev = &cvar_vars;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
var = *prev;
|
||||
if( !var ) break;
|
||||
|
||||
if( var->flags & CVAR_LATCH_AUDIO && var->latched_string )
|
||||
{
|
||||
Cvar_FullSet( var->name, var->latched_string, var->flags );
|
||||
Mem_Free( var->latched_string );
|
||||
var->latched_string = NULL;
|
||||
}
|
||||
prev = &var->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
Cvar_Init
|
||||
|
@ -842,7 +877,8 @@ void Cvar_Init( void )
|
|||
Cmd_AddCommand ("seta", Cvar_SetA_f, "create or change the value of a console variable that will be saved to vars.rc");
|
||||
Cmd_AddCommand ("reset", Cvar_Reset_f, "reset any type variable to initial value" );
|
||||
Cmd_AddCommand ("latch", Cvar_Latched_f, "apply latched values" );
|
||||
Cmd_AddCommand ("vidlatch", Cvar_LatchedVideo_f, "apply latched values for renderer" );
|
||||
Cmd_AddCommand ("vidlatch", Cvar_LatchedVideo_f, "apply latched values for video subsystem" );
|
||||
Cmd_AddCommand ("sndlatch", Cvar_LatchedAudio_f, "apply latched values for audio subsytem" );
|
||||
Cmd_AddCommand ("cvarlist", Cvar_List_f, "display all console variables beginning with the specified prefix" );
|
||||
Cmd_AddCommand ("unsetall", Cvar_Restart_f, "reset all console variables to their default values" );
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ void Sys_Sleep( int msec );
|
|||
void Sys_Init( void );
|
||||
void Sys_Exit( void );
|
||||
void Sys_Abort( void );
|
||||
bool Sys_LoadLibrary ( dll_info_t *dll );
|
||||
bool Sys_LoadLibrary( const char *dll_name, dll_info_t *dll );
|
||||
void* Sys_GetProcAddress ( dll_info_t *dll, const char* name );
|
||||
void Sys_ShellExecute( const char *path, const char *parms, bool exit );
|
||||
byte *Sys_LoadRes( const char *filename, size_t *size );
|
||||
|
|
|
@ -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>
|
|
@ -92,7 +92,7 @@ bool NET_OpenWinSock( void )
|
|||
{
|
||||
// initialize the Winsock function vectors (we do this instead of statically linking
|
||||
// so we can run on Win 3.1, where there isn't necessarily Winsock)
|
||||
if( Sys_LoadLibrary( &winsock_dll ))
|
||||
if( Sys_LoadLibrary( NULL, &winsock_dll ))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -409,8 +409,8 @@ void Sys_CreateInstance( void )
|
|||
// export
|
||||
launch_t CreateHost, CreateBaserc;
|
||||
|
||||
srand( time( NULL )); // init random generator
|
||||
Sys_LoadLibrary( Sys.linked_dll ); // loading library if need
|
||||
srand( time( NULL )); // init random generator
|
||||
Sys_LoadLibrary( NULL, Sys.linked_dll ); // loading library if need
|
||||
|
||||
// pre initializations
|
||||
switch( Sys.app_name )
|
||||
|
@ -424,7 +424,7 @@ void Sys_CreateInstance( void )
|
|||
case HOST_STUDIO:
|
||||
case HOST_WADLIB:
|
||||
case HOST_RIPPER:
|
||||
Sys_LoadLibrary( &baserc_dll ); // load baserc
|
||||
Sys_LoadLibrary( NULL, &baserc_dll ); // load baserc
|
||||
CreateHost = (void *)Sys.linked_dll->main;
|
||||
Host = CreateHost( &com, NULL ); // second interface not allowed
|
||||
Sys.Init = Host->Init;
|
||||
|
@ -970,7 +970,7 @@ void Sys_Exit( void )
|
|||
//=======================================================================
|
||||
// DLL'S MANAGER SYSTEM
|
||||
//=======================================================================
|
||||
bool Sys_LoadLibrary ( dll_info_t *dll )
|
||||
bool Sys_LoadLibrary( const char *dll_name, dll_info_t *dll )
|
||||
{
|
||||
const dllfunc_t *func;
|
||||
bool native_lib = false;
|
||||
|
@ -978,9 +978,12 @@ bool Sys_LoadLibrary ( dll_info_t *dll )
|
|||
|
||||
// check errors
|
||||
if( !dll ) return false; // invalid desc
|
||||
if( !dll->name ) return false;// nothing to load
|
||||
if( dll->link ) return true; // already loaded
|
||||
|
||||
// check and replace names
|
||||
if( dll_name && *dll_name ) dll->name = dll_name;
|
||||
if( !dll->name || !*dll->name ) return false; // nothing to load
|
||||
|
||||
MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s", dll->name );
|
||||
|
||||
if( dll->fcts )
|
||||
|
@ -1003,7 +1006,7 @@ bool Sys_LoadLibrary ( dll_info_t *dll )
|
|||
|
||||
if( native_lib )
|
||||
{
|
||||
if(( dll->main = Sys_GetProcAddress( dll, dll->entry )) == 0)
|
||||
if(( dll->main = Sys_GetProcAddress( dll, dll->entry )) == 0 )
|
||||
{
|
||||
com.sprintf( errorstring, "Sys_LoadLibrary: %s has no valid entry point\n", dll->name );
|
||||
goto error;
|
||||
|
@ -1060,19 +1063,19 @@ error:
|
|||
|
||||
void* Sys_GetProcAddress( dll_info_t *dll, const char* name )
|
||||
{
|
||||
if(!dll || !dll->link) // invalid desc
|
||||
if( !dll || !dll->link ) // invalid desc
|
||||
return NULL;
|
||||
|
||||
return (void *)GetProcAddress (dll->link, name);
|
||||
return (void *)GetProcAddress( dll->link, name );
|
||||
}
|
||||
|
||||
bool Sys_FreeLibrary( dll_info_t *dll )
|
||||
{
|
||||
// invalid desc or alredy freed
|
||||
if(!dll || !dll->link )
|
||||
if( !dll || !dll->link )
|
||||
return false;
|
||||
|
||||
MsgDev(D_NOTE, "Sys_FreeLibrary: Unloading %s\n", dll->name );
|
||||
MsgDev( D_NOTE, "Sys_FreeLibrary: Unloading %s\n", dll->name );
|
||||
FreeLibrary( dll->link );
|
||||
dll->link = NULL;
|
||||
|
||||
|
|
|
@ -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>
|
|
@ -120,6 +120,7 @@ typedef enum
|
|||
CVAR_CHEAT = BIT(9), // can not be changed if cheats are disabled
|
||||
CVAR_NORESTART = BIT(10),// do not clear when a cvar_restart is issued
|
||||
CVAR_LATCH_VIDEO = BIT(11),// save changes until render restart
|
||||
CVAR_LATCH_AUDIO = BIT(12),// save changes until vsound restart
|
||||
} cvar_flags_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -271,8 +272,9 @@ writes into struct by offsets not names
|
|||
*/
|
||||
typedef struct dll_info_s
|
||||
{
|
||||
const char *name; // name of library
|
||||
|
||||
// generic interface
|
||||
const char *name; // library name
|
||||
const dllfunc_t *fcts; // list of dll exports
|
||||
const char *entry; // entrypoint name (internal libs only)
|
||||
void *link; // hinstance of loading library
|
||||
|
@ -579,7 +581,7 @@ typedef struct stdilib_api_s
|
|||
// filesystem simply user interface
|
||||
byte *(*Com_LoadFile)(const char *path, long *filesize ); // load file into heap
|
||||
bool (*Com_WriteFile)(const char *path, const void *data, long len ); // write file into disk
|
||||
bool (*Com_LoadLibrary)( dll_info_t *dll ); // load library
|
||||
bool (*Com_LoadLibrary)( const char *name, dll_info_t *dll ); // load library
|
||||
bool (*Com_FreeLibrary)( dll_info_t *dll ); // free library
|
||||
void*(*Com_GetProcAddress)( dll_info_t *dll, const char* name ); // gpa
|
||||
double (*Com_DoubleTime)( void ); // hi-res timer
|
||||
|
|
|
@ -41,7 +41,7 @@ typedef struct vsound_exp_s
|
|||
void (*StartStreaming)( void );
|
||||
void (*StopStreaming)( void );
|
||||
|
||||
void (*Frame)( int entnum, const vec3_t pos, const vec3_t vel, const vec3_t at, const vec3_t up );
|
||||
void (*Frame)( int entnum, const vec3_t pos, const vec3_t vel, const vec3_t axis[3], bool clear );
|
||||
void (*StopAllSounds)( void );
|
||||
void (*FreeSounds)( void );
|
||||
|
||||
|
@ -57,7 +57,7 @@ typedef struct vsound_imp_s
|
|||
void (*GetSoundSpatialization)( int entnum, vec3_t origin, vec3_t velocity );
|
||||
int (*PointContents)( const vec3_t point );
|
||||
void (*AddLoopingSounds)( void );
|
||||
|
||||
int (*GetServerTime)( void );
|
||||
} vsound_imp_t;
|
||||
|
||||
#endif//VSOUND_API_H
|
12
release.bat
12
release.bat
|
@ -23,7 +23,7 @@ if errorlevel 1 set BUILD_ERROR=1
|
|||
%MSDEV% physic/physic.dsp %CONFIG%"physic - Win32 Release" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% render/render.dsp %CONFIG%"render - Win32 Release" %build_target%
|
||||
%MSDEV% vid_gl/vid_gl.dsp %CONFIG%"vid_gl - Win32 Release" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% server/server.dsp %CONFIG%"server - Win32 Release" %build_target%
|
||||
|
@ -32,7 +32,10 @@ if errorlevel 1 set BUILD_ERROR=1
|
|||
%MSDEV% vprogs/vprogs.dsp %CONFIG%"vprogs - Win32 Release" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% vsound/vsound.dsp %CONFIG%"vsound - Win32 Release" %build_target%
|
||||
%MSDEV% snd_al/snd_al.dsp %CONFIG%"snd_al - Win32 Release" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% snd_dx/snd_dx.dsp %CONFIG%"snd_dx - Win32 Release" %build_target%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
%MSDEV% xtools/xtools.dsp %CONFIG%"xtools - Win32 Release" %build_target%
|
||||
|
@ -62,10 +65,11 @@ if exist client\client.plg del /f /q client\client.plg
|
|||
if exist engine\engine.plg del /f /q engine\engine.plg
|
||||
if exist launch\launch.plg del /f /q launch\launch.plg
|
||||
if exist physic\physic.plg del /f /q physic\physic.plg
|
||||
if exist render\render.plg del /f /q render\render.plg
|
||||
if exist vid_gl\vid_gl.plg del /f /q vid_gl\vid_gl.plg
|
||||
if exist server\server.plg del /f /q server\server.plg
|
||||
if exist vprogs\vprogs.plg del /f /q vprogs\vprogs.plg
|
||||
if exist vsound\vsound.plg del /f /q vsound\vsound.plg
|
||||
if exist snd_al\snd_al.plg del /f /q snd_al\snd_al.plg
|
||||
if exist snd_dx\snd_dx.plg del /f /q snd_dx\snd_dx.plg
|
||||
if exist xtools\xtools.plg del /f /q xtools\xtools.plg
|
||||
|
||||
echo Build succeeded!
|
||||
|
|
|
@ -288,8 +288,9 @@ void CBaseEntity :: ResetParent( void )
|
|||
void CBaseEntity :: SetupPhysics( void )
|
||||
{
|
||||
//rebuild all parents
|
||||
if(pFlags & PF_LINKCHILD) LinkChild( this );
|
||||
if(m_physinit) return;
|
||||
if( pFlags & PF_LINKCHILD ) LinkChild( this );
|
||||
|
||||
if( m_physinit ) return;
|
||||
SetParent(); //set all parents
|
||||
m_physinit = true;
|
||||
PostSpawn();//post spawn
|
||||
|
|
|
@ -52,26 +52,31 @@ class CDecal : public CBaseEntity
|
|||
public:
|
||||
void KeyValue( KeyValueData *pkvd )
|
||||
{
|
||||
if (FStrEq(pkvd->szKeyName, "texture"))
|
||||
if( FStrEq( pkvd->szKeyName, "texture" ))
|
||||
{
|
||||
pev->skin = DECAL_INDEX( pkvd->szValue );
|
||||
if ( pev->skin >= 0 ) return;
|
||||
if( pev->skin >= 0 ) return;
|
||||
Msg( "Can't find decal %s\n", pkvd->szValue );
|
||||
}
|
||||
}
|
||||
void PostSpawn( void ) { if(FStringNull(pev->targetname))MakeDecal(); }
|
||||
void PostSpawn( void ) { if( FStringNull( pev->targetname )) MakeDecal(); }
|
||||
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { MakeDecal(); }
|
||||
void MakeDecal( void )
|
||||
{
|
||||
if ( pev->skin < 0 ) { REMOVE_ENTITY(ENT(pev)); return; }
|
||||
TraceResult trace;
|
||||
int entityIndex, modelIndex;
|
||||
UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace );
|
||||
entityIndex = (short)ENTINDEX(trace.pHit);
|
||||
if ( entityIndex ) modelIndex = (int)VARS(trace.pHit)->modelindex;
|
||||
TraceResult trace;
|
||||
int entityIndex, modelIndex;
|
||||
|
||||
UTIL_TraceLine( pev->origin - Vector( 5, 5, 5 ), pev->origin + Vector( 5, 5, 5 ), ignore_monsters, ENT( pev ), &trace );
|
||||
|
||||
entityIndex = (short)ENTINDEX( trace.pHit );
|
||||
if ( entityIndex ) modelIndex = (int)VARS( trace.pHit )->modelindex;
|
||||
else modelIndex = 0;
|
||||
|
||||
if(FStringNull(pev->targetname)) g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex );
|
||||
if( FStringNull( pev->targetname ))
|
||||
{
|
||||
g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex );
|
||||
}
|
||||
else
|
||||
{
|
||||
MESSAGE_BEGIN( MSG_BROADCAST, gmsg.TempEntity );
|
||||
|
@ -81,7 +86,7 @@ public:
|
|||
WRITE_COORD( pev->origin.z );
|
||||
WRITE_SHORT( (int)pev->skin );
|
||||
WRITE_SHORT( entityIndex );
|
||||
if(entityIndex) WRITE_SHORT( modelIndex );
|
||||
if( entityIndex ) WRITE_SHORT( modelIndex );
|
||||
MESSAGE_END();
|
||||
}
|
||||
|
||||
|
|
|
@ -402,7 +402,7 @@ void CBasePlayer :: TraceAttack( entvars_t *pevAttacker, float flDamage, Vector
|
|||
|
||||
if(bitsDamageType & DMG_NUCLEAR)
|
||||
{
|
||||
m_FadeColor = Vector(255, 255, 255);
|
||||
m_FadeColor = Vector( 255, 255, 255 );
|
||||
m_FadeAlpha = 240;
|
||||
m_iFadeFlags = 0;
|
||||
m_iFadeTime = 25;
|
||||
|
|
|
@ -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>
|
|
@ -28,6 +28,7 @@ void S_SoundList_f( void )
|
|||
{
|
||||
sfx_t *sfx;
|
||||
int i, samples = 0;
|
||||
int totalSfx = 0;
|
||||
|
||||
Msg("\n");
|
||||
Msg(" -samples -hz-- -format- -name--------\n");
|
||||
|
@ -35,46 +36,40 @@ void S_SoundList_f( void )
|
|||
for( i = 0; i < s_numSfx; i++ )
|
||||
{
|
||||
sfx = &s_knownSfx[i];
|
||||
Msg("%4i: ", i);
|
||||
|
||||
if( sfx->loaded )
|
||||
{
|
||||
samples += sfx->samples;
|
||||
Msg("%8i ", sfx->samples);
|
||||
Msg("%5i ", sfx->rate);
|
||||
Msg( "%8i ", sfx->samples );
|
||||
Msg( "%5i ", sfx->rate );
|
||||
|
||||
switch( sfx->format )
|
||||
{
|
||||
case AL_FORMAT_STEREO16: Msg("STEREO16 "); break;
|
||||
case AL_FORMAT_STEREO8: Msg("STEREO8 "); break;
|
||||
case AL_FORMAT_MONO16: Msg("MONO16 "); break;
|
||||
case AL_FORMAT_MONO8: Msg("MONO8 "); break;
|
||||
default: Msg("???????? "); break;
|
||||
case AL_FORMAT_STEREO16: Msg( "STEREO16 " ); break;
|
||||
case AL_FORMAT_STEREO8: Msg( "STEREO8 " ); break;
|
||||
case AL_FORMAT_MONO16: Msg( "MONO16 " ); break;
|
||||
case AL_FORMAT_MONO8: Msg( "MONO8 " ); break;
|
||||
default: Msg( "???????? " ); break;
|
||||
}
|
||||
|
||||
if( sfx->name[0] == '#' ) Msg("%s", &sfx->name[1]);
|
||||
else Msg("sound/%s", sfx->name);
|
||||
if( sfx->name[0] == '#' ) Msg( "%s", &sfx->name[1] );
|
||||
else Msg( "sound/%s", sfx->name );
|
||||
Msg( "\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( sfx->name[0] == '*' ) Msg(" placeholder %s\n", sfx->name);
|
||||
else Msg(" not loaded %s\n", sfx->name);
|
||||
totalSfx++;
|
||||
}
|
||||
}
|
||||
|
||||
Msg("-------------------------------------------\n");
|
||||
Msg("%i total samples\n", samples );
|
||||
Msg("%i total sounds\n", s_numSfx );
|
||||
Msg("%i total sounds\n", totalSfx );
|
||||
Msg("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
|
||||
WAV LOADING
|
||||
|
||||
=======================================================================
|
||||
=======================================================================
|
||||
*/
|
||||
static byte *iff_data;
|
||||
static byte *iff_dataPtr;
|
||||
|
@ -177,7 +172,7 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
|
|||
|
||||
// dind "RIFF" chunk
|
||||
S_FindChunk( "RIFF" );
|
||||
if(!(iff_dataPtr && !com.strncmp(iff_dataPtr+8, "WAVE", 4)))
|
||||
if( !( iff_dataPtr && !com.strncmp( iff_dataPtr + 8, "WAVE", 4 )))
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: missing 'RIFF/WAVE' chunks (%s)\n", name );
|
||||
Mem_Free( buffer );
|
||||
|
@ -186,7 +181,7 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
|
|||
|
||||
// get "fmt " chunk
|
||||
iff_data = iff_dataPtr + 12;
|
||||
S_FindChunk("fmt ");
|
||||
S_FindChunk( "fmt " );
|
||||
if( !iff_dataPtr )
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: missing 'fmt ' chunk (%s)\n", name );
|
||||
|
@ -497,11 +492,11 @@ S_LoadSound
|
|||
*/
|
||||
loadformat_t load_formats[] =
|
||||
{
|
||||
{"sound/%s.%s", "ogg", S_LoadOGG},
|
||||
{"sound/%s.%s", "wav", S_LoadWAV},
|
||||
{"%s.%s", "ogg", S_LoadOGG},
|
||||
{"%s.%s", "wav", S_LoadWAV},
|
||||
{NULL, NULL}
|
||||
{ "sound/%s.%s", "ogg", S_LoadOGG },
|
||||
{ "sound/%s.%s", "wav", S_LoadWAV },
|
||||
{ "%s.%s", "ogg", S_LoadOGG },
|
||||
{ "%s.%s", "wav", S_LoadWAV },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
bool S_LoadSound( sfx_t *sfx )
|
||||
|
@ -526,7 +521,7 @@ bool S_LoadSound( sfx_t *sfx )
|
|||
Mem_Set( &info, 0, sizeof( info ));
|
||||
|
||||
// developer warning
|
||||
if( !anyformat ) MsgDev(D_NOTE, "Note: %s will be loading only with ext .%s\n", loadname, ext );
|
||||
if( !anyformat ) MsgDev( D_NOTE, "Note: %s will be loading only with ext .%s\n", loadname, ext );
|
||||
|
||||
// now try all the formats in the selected list
|
||||
for( format = load_formats; format->formatstring; format++ )
|
||||
|
@ -540,7 +535,7 @@ bool S_LoadSound( sfx_t *sfx )
|
|||
}
|
||||
|
||||
sfx->default_sound = true;
|
||||
MsgDev(D_WARN, "FS_LoadSound: couldn't load %s\n", sfx->name );
|
||||
MsgDev( D_WARN, "FS_LoadSound: couldn't load %s\n", sfx->name );
|
||||
S_CreateDefaultSound( &data, &info );
|
||||
info.loopstart = -1;
|
||||
|
||||
|
@ -576,6 +571,7 @@ sfx_t *S_FindSound( const char *name )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// see if already loaded
|
||||
for( i = 0; i < s_numSfx; i++ )
|
||||
{
|
||||
sfx = &s_knownSfx[i];
|
||||
|
@ -647,7 +643,7 @@ void S_EndRegistration( void )
|
|||
// load everything in
|
||||
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
|
||||
{
|
||||
if( !sfx->name[0] )continue;
|
||||
if( !sfx->name[0] ) continue;
|
||||
S_LoadSound( sfx );
|
||||
}
|
||||
s_registering = false;
|
|
@ -13,8 +13,8 @@
|
|||
static playSound_t s_playSounds[MAX_PLAYSOUNDS];
|
||||
static playSound_t s_freePlaySounds;
|
||||
static playSound_t s_pendingPlaySounds;
|
||||
static channel_t s_channels[MAX_CHANNELS];
|
||||
static listener_t s_listener;
|
||||
static channel_t s_channels[MAX_CHANNELS];
|
||||
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}};
|
||||
|
@ -350,6 +350,7 @@ static playSound_t *S_AllocPlaySound( void )
|
|||
if( ps == &s_freePlaySounds )
|
||||
return NULL; // No free playSounds
|
||||
|
||||
// unlink from freelist
|
||||
ps->prev->next = ps->next;
|
||||
ps->next->prev = ps->prev;
|
||||
|
||||
|
@ -363,6 +364,7 @@ S_FreePlaySound
|
|||
*/
|
||||
static void S_FreePlaySound( playSound_t *ps )
|
||||
{
|
||||
// unlink from channel
|
||||
ps->prev->next = ps->next;
|
||||
ps->next->prev = ps->prev;
|
||||
|
||||
|
@ -397,7 +399,7 @@ static void S_IssuePlaySounds( void )
|
|||
ch = S_PickChannel( ps->entnum, ps->entchannel );
|
||||
if(!ch)
|
||||
{
|
||||
if( ps->sfx->name[0] == '#' ) MsgDev(D_ERROR, "dropped sound %s\n", &ps->sfx->name[1] );
|
||||
if( ps->sfx->name[0] == '#' ) MsgDev( D_ERROR, "dropped sound %s\n", &ps->sfx->name[1] );
|
||||
else MsgDev( D_ERROR, "dropped sound \"sound/%s\"\n", ps->sfx->name );
|
||||
S_FreePlaySound( ps );
|
||||
continue;
|
||||
|
@ -441,16 +443,16 @@ void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, fl
|
|||
playSound_t *ps, *sort;
|
||||
sfx_t *sfx = NULL;
|
||||
|
||||
if(!al_state.initialized )
|
||||
if( !al_state.initialized )
|
||||
return;
|
||||
sfx = S_GetSfxByHandle( handle );
|
||||
if( !sfx ) return;
|
||||
|
||||
// Make sure the sound is loaded
|
||||
// make sure the sound is loaded
|
||||
if( !S_LoadSound( sfx ))
|
||||
return;
|
||||
|
||||
// Allocate a playSound
|
||||
// allocate a playSound
|
||||
ps = S_AllocPlaySound();
|
||||
if( !ps )
|
||||
{
|
||||
|
@ -570,13 +572,13 @@ S_Update
|
|||
Called once each time through the main loop
|
||||
=================
|
||||
*/
|
||||
void S_Update( int clientnum, const vec3_t position, const vec3_t velocity, const vec3_t at, const vec3_t up )
|
||||
void S_Update( int clientnum, const vec3_t position, const vec3_t velocity, const vec3_t axis[3], bool clear )
|
||||
{
|
||||
channel_t *ch;
|
||||
int i;
|
||||
|
||||
if(!al_state.initialized ) return;
|
||||
//if( s_pause->integer ) return;
|
||||
// if( s_pause->integer || clear ) return;
|
||||
|
||||
// bump frame count
|
||||
al_state.framecount++;
|
||||
|
@ -587,12 +589,12 @@ void S_Update( int clientnum, const vec3_t position, const vec3_t velocity, cons
|
|||
VectorSet( s_listener.velocity, velocity[1], velocity[2], -velocity[0] );
|
||||
|
||||
// set listener orientation matrix
|
||||
s_listener.orientation[0] = at[1];
|
||||
s_listener.orientation[1] = -at[2];
|
||||
s_listener.orientation[2] = -at[0];
|
||||
s_listener.orientation[3] = up[1];
|
||||
s_listener.orientation[4] = -up[2];
|
||||
s_listener.orientation[5] = -up[0];
|
||||
s_listener.orientation[0] = axis[0][1];
|
||||
s_listener.orientation[1] = -axis[0][2];
|
||||
s_listener.orientation[2] = -axis[0][0];
|
||||
s_listener.orientation[3] = axis[2][1];
|
||||
s_listener.orientation[4] = -axis[2][2];
|
||||
s_listener.orientation[5] = -axis[2][0];
|
||||
|
||||
palListenerfv(AL_POSITION, s_listener.position);
|
||||
palListenerfv(AL_VELOCITY, s_listener.velocity);
|
||||
|
@ -743,9 +745,11 @@ bool S_Init( void *hInst )
|
|||
{
|
||||
int num_mono_src, num_stereo_src;
|
||||
|
||||
Cmd_ExecuteString( "sndlatch\n" );
|
||||
|
||||
host_sound = Cvar_Get("host_sound", "1", CVAR_SYSTEMINFO, "enable sound system" );
|
||||
s_alDevice = Cvar_Get("s_device", "Generic Software", CVAR_LATCH|CVAR_ARCHIVE, "OpenAL current device name" );
|
||||
s_soundfx = Cvar_Get("s_soundfx", "1", CVAR_LATCH|CVAR_ARCHIVE, "allow OpenAl extensions" );
|
||||
s_alDevice = Cvar_Get("s_device", "Generic Software", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "OpenAL current device name" );
|
||||
s_soundfx = Cvar_Get("s_soundfx", "1", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "allow OpenAl extensions" );
|
||||
s_check_errors = Cvar_Get("s_check_errors", "1", CVAR_ARCHIVE, "ignore audio engine errors" );
|
||||
s_volume = Cvar_Get("s_volume", "1.0", CVAR_ARCHIVE, "sound volume" );
|
||||
s_musicvolume = Cvar_Get("s_musicvolume", "1.0", CVAR_ARCHIVE, "background music volume" );
|
|
@ -160,8 +160,8 @@ failed:
|
|||
|
||||
// release openal at all
|
||||
Sys_FreeLibrary( &openal_dll );
|
||||
Mem_Set(&al_config, 0, sizeof(alconfig_t));
|
||||
Mem_Set(&al_state, 0, sizeof(alstate_t));
|
||||
Mem_Set( &al_config, 0, sizeof( alconfig_t ));
|
||||
Mem_Set( &al_state, 0, sizeof( alstate_t ));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -331,7 +331,7 @@ static void S_InitExtensions( void )
|
|||
|
||||
bool S_Init_OpenAL( void )
|
||||
{
|
||||
Sys_LoadLibrary( &openal_dll );
|
||||
Sys_LoadLibrary( NULL, &openal_dll );
|
||||
|
||||
if( !openal_dll.link )
|
||||
{
|
|
@ -1,24 +1,24 @@
|
|||
# Microsoft Developer Studio Project File - Name="vsound" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Project File - Name="snd_al" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=vsound - Win32 Debug
|
||||
CFG=snd_al - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "vsound.mak".
|
||||
!MESSAGE NMAKE /f "snd_al.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "vsound.mak" CFG="vsound - Win32 Debug"
|
||||
!MESSAGE NMAKE /f "snd_al.mak" CFG="snd_al - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "vsound - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "vsound - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "snd_al - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "snd_al - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
|
@ -29,7 +29,7 @@ CPP=cl.exe
|
|||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "vsound - Win32 Release"
|
||||
!IF "$(CFG)" == "snd_al - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
|
@ -38,8 +38,8 @@ RSC=rc.exe
|
|||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "..\temp\vsound\!release"
|
||||
# PROP Intermediate_Dir "..\temp\vsound\!release"
|
||||
# PROP Output_Dir "..\temp\snd_al\!release"
|
||||
# PROP Intermediate_Dir "..\temp\snd_al\!release"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PLATFORM_EXPORTS" /YX /FD /c
|
||||
|
@ -57,16 +57,16 @@ LINK32=link.exe
|
|||
# ADD LINK32 libogg.lib vorbis.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libcmt.lib" /opt:nowin98
|
||||
# SUBTRACT LINK32 /profile
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\vsound\!release
|
||||
InputPath=\Xash3D\src_main\temp\vsound\!release\vsound.dll
|
||||
TargetDir=\Xash3D\src_main\temp\snd_al\!release
|
||||
InputPath=\Xash3D\src_main\temp\snd_al\!release\snd_al.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\vsound.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\vsound.dll "D:\Xash3D\bin\vsound.dll"
|
||||
"D:\Xash3D\bin\snd_al.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\snd_al.dll "D:\Xash3D\bin\snd_al.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "vsound - Win32 Debug"
|
||||
!ELSEIF "$(CFG)" == "snd_al - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
|
@ -75,8 +75,8 @@ SOURCE="$(InputPath)"
|
|||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\temp\vsound\!debug"
|
||||
# PROP Intermediate_Dir "..\temp\vsound\!debug"
|
||||
# PROP Output_Dir "..\temp\snd_al\!debug"
|
||||
# PROP Intermediate_Dir "..\temp\snd_al\!debug"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PLATFORM_EXPORTS" /YX /FD /GZ /c
|
||||
|
@ -94,12 +94,12 @@ LINK32=link.exe
|
|||
# ADD LINK32 libogg.lib vorbis.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libcmt.lib" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /incremental:no /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\vsound\!debug
|
||||
InputPath=\Xash3D\src_main\temp\vsound\!debug\vsound.dll
|
||||
TargetDir=\Xash3D\src_main\temp\snd_al\!debug
|
||||
InputPath=\Xash3D\src_main\temp\snd_al\!debug\snd_al.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\vsound.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\vsound.dll "D:\Xash3D\bin\vsound.dll"
|
||||
"D:\Xash3D\bin\snd_al.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\snd_al.dll "D:\Xash3D\bin\snd_al.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
|
@ -107,8 +107,8 @@ SOURCE="$(InputPath)"
|
|||
|
||||
# Begin Target
|
||||
|
||||
# Name "vsound - Win32 Release"
|
||||
# Name "vsound - Win32 Debug"
|
||||
# Name "snd_al - Win32 Release"
|
||||
# Name "snd_al - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
|
@ -169,7 +169,7 @@ void S_Activate( bool active );
|
|||
void S_SoundList_f( void );
|
||||
bool S_CheckForErrors( void );
|
||||
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_Update( int clientnum, const vec3_t pos, const vec3_t vel, const vec3_t at, const vec3_t up );
|
||||
void S_Update( int entnum, const vec3_t pos, const vec3_t vel, const vec3_t axis[3], bool clear );
|
||||
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 );
|
|
@ -0,0 +1,743 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2009 ©
|
||||
// s_direct.c - sound hardware output
|
||||
//=======================================================================
|
||||
|
||||
#include <dsound.h>
|
||||
#include "sound.h"
|
||||
|
||||
#define iDirectSoundCreate( a, b, c ) pDirectSoundCreate( a, b, c )
|
||||
|
||||
static HRESULT ( _stdcall *pDirectSoundCreate)(GUID* lpGUID, LPDIRECTSOUND* lplpDS, IUnknown* pUnkOuter );
|
||||
|
||||
static dllfunc_t dsound_funcs[] =
|
||||
{
|
||||
{ "DirectSoundCreate", (void **) &pDirectSoundCreate },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
dll_info_t dsound_dll = { "dsound.dll", dsound_funcs, NULL, NULL, NULL, false, 0, 0 };
|
||||
|
||||
// 64K is > 1 second at 16-bit, 22050 Hz
|
||||
#define WAV_BUFFERS 64
|
||||
#define WAV_MASK 0x3F
|
||||
#define WAV_BUFFER_SIZE 0x0400
|
||||
#define SECONDARY_BUFFER_SIZE 0x10000
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SIS_SUCCESS,
|
||||
SIS_FAILURE,
|
||||
SIS_NOTAVAIL
|
||||
} si_state_t;
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
Global variables. Must be visible to window-procedure function
|
||||
so it can unlock and free the data block after it has been played.
|
||||
=======================================================================
|
||||
*/
|
||||
DWORD locksize;
|
||||
HANDLE hData;
|
||||
HPSTR lpData, lpData2;
|
||||
HGLOBAL hWaveHdr;
|
||||
LPWAVEHDR lpWaveHdr;
|
||||
HWAVEOUT hWaveOut;
|
||||
WAVEOUTCAPS wavecaps;
|
||||
DWORD gSndBufSize;
|
||||
MMTIME mmstarttime;
|
||||
LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf;
|
||||
LPDIRECTSOUND pDS;
|
||||
|
||||
bool SNDDMA_InitDirect( void *hInst );
|
||||
bool SNDDMA_InitWav( void );
|
||||
void SNDDMA_FreeSound( void );
|
||||
|
||||
static const char *DSoundError( int error )
|
||||
{
|
||||
switch( error )
|
||||
{
|
||||
case DSERR_BUFFERLOST:
|
||||
return "DSERR_BUFFERLOST";
|
||||
case DSERR_INVALIDCALL:
|
||||
return "DSERR_INVALIDCALLS";
|
||||
case DSERR_INVALIDPARAM:
|
||||
return "DSERR_INVALIDPARAM";
|
||||
case DSERR_PRIOLEVELNEEDED:
|
||||
return "DSERR_PRIOLEVELNEEDED";
|
||||
}
|
||||
return "Unknown Error";
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
DS_CreateBuffers
|
||||
==================
|
||||
*/
|
||||
static bool DS_CreateBuffers( void *hInst )
|
||||
{
|
||||
DSBUFFERDESC dsbuf;
|
||||
DSBCAPS dsbcaps;
|
||||
WAVEFORMATEX pformat, format;
|
||||
|
||||
Mem_Set( &format, 0, sizeof( format ));
|
||||
|
||||
format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
format.nChannels = dma.channels;
|
||||
format.wBitsPerSample = dma.samplebits;
|
||||
format.nSamplesPerSec = dma.speed;
|
||||
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
|
||||
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
|
||||
format.cbSize = 0;
|
||||
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: initialize\n" );
|
||||
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: setting EXCLUSIVE coop level " );
|
||||
if( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, hInst, DSSCL_EXCLUSIVE ))
|
||||
{
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return false;
|
||||
}
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
|
||||
// get access to the primary buffer, if possible, so we can set the sound hardware format
|
||||
Mem_Set( &dsbuf, 0, sizeof( dsbuf ));
|
||||
dsbuf.dwSize = sizeof( DSBUFFERDESC );
|
||||
dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
dsbuf.dwBufferBytes = 0;
|
||||
dsbuf.lpwfxFormat = NULL;
|
||||
|
||||
Mem_Set( &dsbcaps, 0, sizeof( dsbcaps ));
|
||||
dsbcaps.dwSize = sizeof( dsbcaps );
|
||||
primary_format_set = false;
|
||||
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: creating primary buffer " );
|
||||
if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSPBuf, NULL ) == DS_OK )
|
||||
{
|
||||
pformat = format;
|
||||
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
if( pDSPBuf->lpVtbl->SetFormat( pDSPBuf, &pformat ) != DS_OK )
|
||||
{
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: setting primary sound format - failed\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: setting primary sound format - ok\n" );
|
||||
primary_format_set = true;
|
||||
}
|
||||
}
|
||||
else MsgDev( D_NOTE, "- failed\n" );
|
||||
|
||||
if( !primary_format_set || !s_primary->integer )
|
||||
{
|
||||
// create the secondary buffer we'll actually work with
|
||||
Mem_Set( &dsbuf, 0, sizeof( dsbuf ));
|
||||
dsbuf.dwSize = sizeof( DSBUFFERDESC );
|
||||
dsbuf.dwFlags = (DSBCAPS_CTRLFREQUENCY|DSBCAPS_LOCSOFTWARE);
|
||||
dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
|
||||
dsbuf.lpwfxFormat = &format;
|
||||
|
||||
Mem_Set( &dsbcaps, 0, sizeof( dsbcaps ));
|
||||
dsbcaps.dwSize = sizeof( dsbcaps );
|
||||
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: creating secondary buffer " );
|
||||
if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSBuf, NULL ) == DS_OK )
|
||||
{
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// couldn't get hardware, fallback to software.
|
||||
dsbuf.dwFlags = (DSBCAPS_LOCSOFTWARE|DSBCAPS_GETCURRENTPOSITION2);
|
||||
if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSBuf, NULL ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
MsgDev( D_INFO, "- failed. forced to software\n" );
|
||||
}
|
||||
|
||||
dma.channels = format.nChannels;
|
||||
dma.samplebits = format.wBitsPerSample;
|
||||
dma.speed = format.nSamplesPerSec;
|
||||
|
||||
if( pDSBuf->lpVtbl->GetCaps( pDSBuf, &dsbcaps ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "DS_CreateBuffers: GetCaps failed\n");
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: using secondary sound buffer\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: using primary sound buffer\n" );
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: setting WRITEPRIMARY coop level " );
|
||||
if( pDS->lpVtbl->SetCooperativeLevel( pDS, hInst, DSSCL_WRITEPRIMARY ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
|
||||
if( pDSPBuf->lpVtbl->GetCaps( pDSPBuf, &dsbcaps ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "DS_CreateBuffers: GetCaps failed\n");
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
pDSBuf = pDSPBuf;
|
||||
}
|
||||
|
||||
// make sure mixer is active
|
||||
if( pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "DS_CreateBuffers: looped sound play failed\n" );
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
|
||||
// we don't want anyone to access the buffer directly w/o locking it first
|
||||
lpData = NULL;
|
||||
dma.samplepos = 0;
|
||||
snd_hwnd = (HWND)hInst;
|
||||
gSndBufSize = dsbcaps.dwBufferBytes;
|
||||
dma.samples = gSndBufSize / (dma.samplebits / 8 );
|
||||
dma.submission_chunk = 1;
|
||||
dma.buffer = (byte *)lpData;
|
||||
sample16 = (dma.samplebits / 8) - 1;
|
||||
|
||||
SNDDMA_BeginPainting();
|
||||
if( dma.buffer ) Mem_Set( dma.buffer, 0, dma.samples * dma.samplebits / 8 );
|
||||
SNDDMA_Submit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
DS_DestroyBuffers
|
||||
==================
|
||||
*/
|
||||
static void DS_DestroyBuffers( void )
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_DestroyBuffers: shutdown\n" );
|
||||
|
||||
if( pDS )
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_DestroyBuffers: setting NORMAL coop level\n" );
|
||||
pDS->lpVtbl->SetCooperativeLevel( pDS, snd_hwnd, DSSCL_NORMAL );
|
||||
}
|
||||
|
||||
if( pDSBuf )
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_DestroyBuffers: stopping and releasing sound buffer\n" );
|
||||
pDSBuf->lpVtbl->Stop( pDSBuf );
|
||||
pDSBuf->lpVtbl->Release( pDSBuf );
|
||||
}
|
||||
|
||||
// only release primary buffer if it's not also the mixing buffer we just released
|
||||
if( pDSPBuf && ( pDSBuf != pDSPBuf ))
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_DestroyBuffers: releasing primary buffer\n" );
|
||||
pDSPBuf->lpVtbl->Release( pDSPBuf );
|
||||
}
|
||||
|
||||
pDSBuf = NULL;
|
||||
pDSPBuf = NULL;
|
||||
dma.buffer = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDMA_FreeSound
|
||||
==================
|
||||
*/
|
||||
void SNDDMA_FreeSound( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( pDS )
|
||||
{
|
||||
DS_DestroyBuffers();
|
||||
pDS->lpVtbl->Release( pDS );
|
||||
Sys_FreeLibrary( &dsound_dll );
|
||||
}
|
||||
|
||||
if( hWaveOut )
|
||||
{
|
||||
waveOutReset( hWaveOut );
|
||||
|
||||
if( lpWaveHdr )
|
||||
{
|
||||
for( i = 0; i < WAV_BUFFERS; i++ )
|
||||
waveOutUnprepareHeader( hWaveOut, lpWaveHdr + i, sizeof( WAVEHDR ));
|
||||
}
|
||||
|
||||
waveOutClose( hWaveOut );
|
||||
|
||||
if( hWaveHdr )
|
||||
{
|
||||
GlobalUnlock( hWaveHdr );
|
||||
GlobalFree( hWaveHdr );
|
||||
}
|
||||
|
||||
if( hData )
|
||||
{
|
||||
GlobalUnlock( hData );
|
||||
GlobalFree( hData );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pDS = NULL;
|
||||
pDSBuf = NULL;
|
||||
pDSPBuf = NULL;
|
||||
hWaveOut = 0;
|
||||
hData = 0;
|
||||
hWaveHdr = 0;
|
||||
lpData = NULL;
|
||||
lpWaveHdr = NULL;
|
||||
dsound_init = false;
|
||||
wav_init = false;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDMA_InitDirect
|
||||
|
||||
Direct-Sound support
|
||||
==================
|
||||
*/
|
||||
si_state_t SNDDMA_InitDirect( void *hInst )
|
||||
{
|
||||
DSCAPS dscaps;
|
||||
HRESULT hresult;
|
||||
|
||||
dma.channels = 2;
|
||||
dma.samplebits = 16;
|
||||
|
||||
switch( s_khz->integer )
|
||||
{
|
||||
case 44: dma.speed = 44100; break;
|
||||
case 22: dma.speed = 22050; break;
|
||||
default: dma.speed = 11025; break;
|
||||
}
|
||||
|
||||
MsgDev( D_NOTE, "SNDDMA_InitDirect: initializing DirectSound ");
|
||||
|
||||
if ( !dsound_dll.link )
|
||||
{
|
||||
if( !Sys_LoadLibrary( NULL, &dsound_dll ))
|
||||
{
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
}
|
||||
|
||||
MsgDev( D_NOTE, "SNDDMA_InitDirect: creating DS object " );
|
||||
if(( hresult = iDirectSoundCreate( NULL, &pDS, NULL )) != DS_OK )
|
||||
{
|
||||
if( hresult != DSERR_ALLOCATED )
|
||||
{
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
MsgDev( D_NOTE, "- failed, hardware already in use\n" );
|
||||
return SIS_NOTAVAIL;
|
||||
}
|
||||
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
dscaps.dwSize = sizeof( dscaps );
|
||||
|
||||
if( pDS->lpVtbl->GetCaps( pDS, &dscaps ) != DS_OK )
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: GetCaps failed\n");
|
||||
|
||||
if( dscaps.dwFlags & DSCAPS_EMULDRIVER )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: no DSound driver found\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
if( !DS_CreateBuffers( hInst ))
|
||||
return SIS_FAILURE;
|
||||
|
||||
dsound_init = true;
|
||||
|
||||
return SIS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDM_InitWav
|
||||
|
||||
Crappy windows multimedia base
|
||||
==================
|
||||
*/
|
||||
si_state_t SNDDMA_InitWav( void )
|
||||
{
|
||||
WAVEFORMATEX format;
|
||||
HRESULT hr;
|
||||
int i;
|
||||
|
||||
snd_sent = 0;
|
||||
snd_completed = 0;
|
||||
|
||||
dma.channels = 2;
|
||||
dma.samplebits = 16;
|
||||
|
||||
switch( s_khz->integer )
|
||||
{
|
||||
case 44: dma.speed = 44100; break;
|
||||
case 22: dma.speed = 22050; break;
|
||||
default: dma.speed = 11025; break;
|
||||
}
|
||||
|
||||
Mem_Set( &format, 0, sizeof( format ));
|
||||
format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
format.nChannels = dma.channels;
|
||||
format.wBitsPerSample = dma.samplebits;
|
||||
format.nSamplesPerSec = dma.speed;
|
||||
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
|
||||
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
|
||||
format.cbSize = 0;
|
||||
|
||||
// open a waveform device for output using window callback.
|
||||
MsgDev( D_NOTE, "SNDDMA_InitWav: initializing wave sound " );
|
||||
if((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, &format, 0, 0, CALLBACK_NULL)) != MMSYSERR_NOERROR )
|
||||
{
|
||||
if( hr != MMSYSERR_ALLOCATED )
|
||||
{
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
MsgDev( D_NOTE, "- failed, hardware already in use\n" );
|
||||
return SIS_NOTAVAIL;
|
||||
}
|
||||
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
|
||||
// allocate and lock memory for the waveform data. The memory
|
||||
// for waveform data must be globally allocated with
|
||||
// GMEM_MOVEABLE and GMEM_SHARE flags.
|
||||
|
||||
gSndBufSize = WAV_BUFFERS * WAV_BUFFER_SIZE;
|
||||
hData = GlobalAlloc( GMEM_MOVEABLE|GMEM_SHARE, gSndBufSize );
|
||||
if( !hData )
|
||||
{
|
||||
SNDDMA_FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
lpData = GlobalLock( hData );
|
||||
if( !lpData )
|
||||
{
|
||||
SNDDMA_FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
Mem_Set( lpData, 0, gSndBufSize );
|
||||
|
||||
// Allocate and lock memory for the header. This memory must
|
||||
// also be globally allocated with GMEM_MOVEABLE and
|
||||
// GMEM_SHARE flags.
|
||||
hWaveHdr = GlobalAlloc( GMEM_MOVEABLE|GMEM_SHARE, (DWORD)sizeof( WAVEHDR ) * WAV_BUFFERS );
|
||||
|
||||
if( hWaveHdr == NULL )
|
||||
{
|
||||
SNDDMA_FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
lpWaveHdr = (LPWAVEHDR)GlobalLock( hWaveHdr );
|
||||
|
||||
if( lpWaveHdr == NULL )
|
||||
{
|
||||
SNDDMA_FreeSound();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
Mem_Set( lpWaveHdr, 0, sizeof( WAVEHDR ) * WAV_BUFFERS );
|
||||
|
||||
// After allocation, set up and prepare headers.
|
||||
for( i = 0; i < WAV_BUFFERS; i++ )
|
||||
{
|
||||
lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE;
|
||||
lpWaveHdr[i].lpData = lpData + i * WAV_BUFFER_SIZE;
|
||||
|
||||
if( waveOutPrepareHeader( hWaveOut, lpWaveHdr+i, sizeof( WAVEHDR )) != MMSYSERR_NOERROR )
|
||||
{
|
||||
SNDDMA_FreeSound();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
dma.samplepos = 0;
|
||||
dma.samples = gSndBufSize / ( dma.samplebits / 8 );
|
||||
dma.submission_chunk = 512;
|
||||
dma.buffer = (byte *)lpData;
|
||||
sample16 = (dma.samplebits / 8) - 1;
|
||||
wav_init = true;
|
||||
|
||||
return SIS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SNDDMA_Init
|
||||
|
||||
Try to find a sound device to mix for.
|
||||
Returns false if nothing is found.
|
||||
==================
|
||||
*/
|
||||
int SNDDMA_Init( void *hInst )
|
||||
{
|
||||
si_state_t stat = SIS_FAILURE; // assume DirectSound won't initialize
|
||||
|
||||
Mem_Set( &dma, 0, sizeof( dma ));
|
||||
|
||||
s_wavonly = Cvar_Get( "s_wavonly", "0", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "force to use WaveOutput only" );
|
||||
dsound_init = wav_init = 0;
|
||||
|
||||
// init DirectSound
|
||||
if( !s_wavonly->integer )
|
||||
{
|
||||
if( snd_firsttime || snd_isdirect )
|
||||
{
|
||||
stat = SNDDMA_InitDirect( hInst );
|
||||
|
||||
if( stat == SIS_SUCCESS )
|
||||
{
|
||||
snd_isdirect = true;
|
||||
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_INFO, "Audio: DirectSound\n" );
|
||||
}
|
||||
else snd_isdirect = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if DirectSound didn't succeed in initializing, try to initialize
|
||||
// waveOut sound, unless DirectSound failed because the hardware is
|
||||
// already allocated (in which case the user has already chosen not
|
||||
// to have sound)
|
||||
if( !dsound_init && ( stat != SIS_NOTAVAIL ))
|
||||
{
|
||||
if( snd_firsttime || snd_iswave )
|
||||
{
|
||||
stat = SNDDMA_InitWav();
|
||||
|
||||
if( stat == SIS_SUCCESS )
|
||||
{
|
||||
snd_iswave = true;
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_INFO, "Audio: WaveOutput\n" );
|
||||
}
|
||||
else snd_iswave = false;
|
||||
}
|
||||
}
|
||||
snd_buffer_count = 1;
|
||||
|
||||
if( !dsound_init && !wav_init )
|
||||
{
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_ERROR, "SNDDMA_Init: can't initialize sound device\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
snd_firsttime = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_GetDMAPos
|
||||
|
||||
return the current sample position (in mono samples read)
|
||||
inside the recirculating dma buffer, so the mixing code will know
|
||||
how many sample are required to fill it up.
|
||||
===============
|
||||
*/
|
||||
int SNDDMA_GetDMAPos( void )
|
||||
{
|
||||
int s;
|
||||
|
||||
if( dsound_init )
|
||||
{
|
||||
MMTIME mmtime;
|
||||
DWORD dwWrite;
|
||||
|
||||
mmtime.wType = TIME_SAMPLES;
|
||||
pDSBuf->lpVtbl->GetCurrentPosition( pDSBuf, &mmtime.u.sample, &dwWrite );
|
||||
s = mmtime.u.sample - mmstarttime.u.sample;
|
||||
}
|
||||
else if( wav_init )
|
||||
{
|
||||
s = snd_sent * WAV_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
|
||||
s >>= sample16;
|
||||
s &= (dma.samples - 1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_BeginPainting
|
||||
|
||||
Makes sure dma.buffer is valid
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_BeginPainting( void )
|
||||
{
|
||||
int reps;
|
||||
DWORD dwSize2;
|
||||
DWORD *pbuf, *pbuf2;
|
||||
HRESULT hr;
|
||||
DWORD dwStatus;
|
||||
|
||||
if( !pDSBuf ) return;
|
||||
|
||||
// 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_BeginPainting: 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, "S_TransferStereo16: lock failed with error '%s'\n", DSoundError( hr ));
|
||||
S_Shutdown ();
|
||||
return;
|
||||
}
|
||||
else pDSBuf->lpVtbl->Restore( pDSBuf );
|
||||
|
||||
if( ++reps > 2 ) return;
|
||||
}
|
||||
dma.buffer = (byte *)pbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_Submit
|
||||
|
||||
Send sound to device if buffer isn't really the dma buffer
|
||||
Also unlocks the dsound buffer
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_Submit( void )
|
||||
{
|
||||
LPWAVEHDR h;
|
||||
int wResult;
|
||||
|
||||
if( !dma.buffer )
|
||||
return;
|
||||
|
||||
// unlock the dsound buffer
|
||||
if( pDSBuf ) pDSBuf->lpVtbl->Unlock( pDSBuf, dma.buffer, locksize, NULL, 0 );
|
||||
|
||||
if( !wav_init ) return;
|
||||
|
||||
// find which sound blocks have completed
|
||||
while( 1 )
|
||||
{
|
||||
if( snd_completed == snd_sent )
|
||||
break;
|
||||
|
||||
if(!( lpWaveHdr[snd_completed & WAV_MASK].dwFlags & WHDR_DONE ))
|
||||
break;
|
||||
snd_completed++; // this buffer has been played
|
||||
}
|
||||
|
||||
// submit a few new sound blocks
|
||||
while(((snd_sent - snd_completed) >> sample16 ) < 8 )
|
||||
{
|
||||
h = lpWaveHdr + ( snd_sent & WAV_MASK );
|
||||
|
||||
if( paintedtime / 256 <= snd_sent )
|
||||
break;
|
||||
snd_sent++;
|
||||
|
||||
// Now the data block can be sent to the output device. The
|
||||
// waveOutWrite function returns immediately and waveform
|
||||
// data is sent to the output device in the background.
|
||||
wResult = waveOutWrite( hWaveOut, h, sizeof( WAVEHDR ));
|
||||
|
||||
if( wResult != MMSYSERR_NOERROR )
|
||||
{
|
||||
MsgDev( D_ERROR, "S_TransferStereo16: failed to write block to device\n" );
|
||||
SNDDMA_FreeSound ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_Shutdown
|
||||
|
||||
Reset the sound device for exiting
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_Shutdown( void )
|
||||
{
|
||||
SNDDMA_FreeSound();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===========
|
||||
S_Activate
|
||||
|
||||
Called when the main window gains or loses focus.
|
||||
The window have been destroyed and recreated
|
||||
between a deactivate and an activate.
|
||||
===========
|
||||
*/
|
||||
void S_Activate( bool active )
|
||||
{
|
||||
if( active )
|
||||
{
|
||||
if( pDS && snd_hwnd && snd_isdirect )
|
||||
DS_CreateBuffers( snd_hwnd );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pDS && snd_hwnd && snd_isdirect )
|
||||
DS_DestroyBuffers();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// s_export.c - sound library main
|
||||
//=======================================================================
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
vsound_imp_t si;
|
||||
stdlib_api_t com;
|
||||
byte *sndpool;
|
||||
|
||||
vsound_exp_t DLLEXPORT *CreateAPI( stdlib_api_t *input, vsound_imp_t *engfuncs )
|
||||
{
|
||||
static vsound_exp_t snd;
|
||||
|
||||
com = *input;
|
||||
|
||||
// Sys_LoadLibrary can create fake instance, to check
|
||||
// api version and api size, but second argument will be 0
|
||||
// and always make exception, run simply check for avoid it
|
||||
if( engfuncs ) si = *engfuncs;
|
||||
|
||||
// generic functions
|
||||
snd.api_size = sizeof( vsound_exp_t );
|
||||
snd.com_size = sizeof( stdlib_api_t );
|
||||
|
||||
snd.Init = S_Init;
|
||||
snd.Shutdown = S_Shutdown;
|
||||
|
||||
// sound manager
|
||||
snd.BeginRegistration = S_BeginRegistration;
|
||||
snd.RegisterSound = S_RegisterSound;
|
||||
snd.EndRegistration = S_EndRegistration;
|
||||
|
||||
snd.StartSound = S_StartSound;
|
||||
snd.StreamRawSamples = S_StreamRawSamples;
|
||||
snd.AddLoopingSound = S_AddLoopingSound;
|
||||
snd.StartLocalSound = S_StartLocalSound;
|
||||
snd.StartBackgroundTrack = S_StartBackgroundTrack;
|
||||
snd.StopBackgroundTrack = S_StopBackgroundTrack;
|
||||
|
||||
snd.StartStreaming = S_StartStreaming;
|
||||
snd.StopStreaming = S_StopStreaming;
|
||||
|
||||
snd.Frame = S_Update;
|
||||
snd.StopAllSounds = S_StopAllSounds;
|
||||
snd.FreeSounds = S_FreeSounds;
|
||||
|
||||
snd.Activate = S_Activate;
|
||||
|
||||
return &snd;
|
||||
}
|
|
@ -0,0 +1,609 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// s_load.c - sound managment
|
||||
//=======================================================================
|
||||
|
||||
#include "sound.h"
|
||||
#include "byteorder.h"
|
||||
|
||||
// during registration it is possible to have more sounds
|
||||
// than could actually be referenced during gameplay,
|
||||
// because we don't want to free anything until we are
|
||||
// sure we won't need it.
|
||||
#define MAX_SFX 4096
|
||||
|
||||
static sfx_t s_knownSfx[MAX_SFX];
|
||||
static int s_numSfx = 0;
|
||||
bool s_registering = false;
|
||||
int s_registration_sequence = 0;
|
||||
|
||||
typedef struct loadformat_s
|
||||
{
|
||||
char *formatstring;
|
||||
char *ext;
|
||||
bool (*loadfunc)( const char *name, byte **wav, wavinfo_t *info );
|
||||
} loadformat_t;
|
||||
|
||||
/*
|
||||
=================
|
||||
S_SoundList_f
|
||||
=================
|
||||
*/
|
||||
void S_SoundList_f( void )
|
||||
{
|
||||
int i;
|
||||
sfx_t *sfx;
|
||||
sfxcache_t *sc;
|
||||
int size, totalSfx = 0;
|
||||
int totalSize = 0;
|
||||
|
||||
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
|
||||
{
|
||||
if( !sfx->registration_sequence )
|
||||
continue;
|
||||
|
||||
sc = sfx->cache;
|
||||
if( sc )
|
||||
{
|
||||
size = sc->length * sc->width * (sc->stereo + 1);
|
||||
totalSize += size;
|
||||
if( sc->loopstart >= 0 ) Msg( "L" );
|
||||
else Msg( " " );
|
||||
|
||||
if( sfx->name[0] == '#' )
|
||||
Msg( " (%2db) %s : %s\n", sc->width * 8, memprint( size ), &sfx->name[1] );
|
||||
else Msg( " (%2db) %s : sound/%s\n", sc->width * 8, memprint( size ), sfx->name );
|
||||
totalSfx++;
|
||||
}
|
||||
}
|
||||
|
||||
Msg("-------------------------------------------\n");
|
||||
Msg("%i total sounds\n", totalSfx );
|
||||
Msg("%s total memory\n", memprint( totalSize ));
|
||||
Msg("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
S_ResampleSfx
|
||||
================
|
||||
*/
|
||||
void S_ResampleSfx( sfx_t *sfx, int inrate, int inwidth, byte *data )
|
||||
{
|
||||
float stepscale;
|
||||
int outcount, srcsample;
|
||||
int i, sample, samplefrac, fracstep;
|
||||
sfxcache_t *sc;
|
||||
|
||||
if( !sfx ) return;
|
||||
sc = sfx->cache;
|
||||
if( !sc ) return;
|
||||
|
||||
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
||||
|
||||
outcount = sc->length / stepscale;
|
||||
sc->length = outcount;
|
||||
if( sc->loopstart != -1 )
|
||||
sc->loopstart = sc->loopstart / stepscale;
|
||||
|
||||
sc->speed = dma.speed;
|
||||
if( s_loadas8bit->integer )
|
||||
sc->width = 1;
|
||||
else sc->width = inwidth;
|
||||
sc->stereo = 0;
|
||||
|
||||
// resample / decimate to the current source rate
|
||||
if( stepscale == 1 && inwidth == 1 && sc->width == 1 )
|
||||
{
|
||||
// fast special case
|
||||
for( i = 0; i < outcount; i++ )
|
||||
((signed char *)sc->data)[i] = (int)((unsigned char)(data[i]) - 128);
|
||||
}
|
||||
else
|
||||
{
|
||||
// general case
|
||||
samplefrac = 0;
|
||||
fracstep = stepscale * 256;
|
||||
for( i = 0; i < outcount; i++ )
|
||||
{
|
||||
srcsample = samplefrac >> 8;
|
||||
samplefrac += fracstep;
|
||||
|
||||
if( inwidth == 2 ) sample = LittleShort(((short *)data)[srcsample] );
|
||||
else sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
|
||||
|
||||
if( sc->width == 2 ) ((short *)sc->data)[i] = sample;
|
||||
else ((signed char *)sc->data)[i] = sample >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
WAV loading
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
static byte *iff_data;
|
||||
static byte *iff_dataPtr;
|
||||
static byte *iff_end;
|
||||
static byte *iff_lastChunk;
|
||||
static int iff_chunkLen;
|
||||
|
||||
/*
|
||||
=================
|
||||
S_GetLittleShort
|
||||
=================
|
||||
*/
|
||||
static short S_GetLittleShort( void )
|
||||
{
|
||||
short val = 0;
|
||||
|
||||
val += (*(iff_dataPtr+0) << 0);
|
||||
val += (*(iff_dataPtr+1) << 8);
|
||||
iff_dataPtr += 2;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_GetLittleLong
|
||||
=================
|
||||
*/
|
||||
static int S_GetLittleLong( void )
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
val += (*(iff_dataPtr+0) << 0);
|
||||
val += (*(iff_dataPtr+1) << 8);
|
||||
val += (*(iff_dataPtr+2) << 16);
|
||||
val += (*(iff_dataPtr+3) << 24);
|
||||
iff_dataPtr += 4;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FindNextChunk
|
||||
=================
|
||||
*/
|
||||
static void S_FindNextChunk( const char *name )
|
||||
{
|
||||
while( 1 )
|
||||
{
|
||||
iff_dataPtr = iff_lastChunk;
|
||||
if( iff_dataPtr >= iff_end )
|
||||
{
|
||||
// didn't find the chunk
|
||||
iff_dataPtr = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
iff_dataPtr += 4;
|
||||
iff_chunkLen = S_GetLittleLong();
|
||||
if (iff_chunkLen < 0)
|
||||
{
|
||||
iff_dataPtr = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
iff_dataPtr -= 8;
|
||||
iff_lastChunk = iff_dataPtr + 8 + ((iff_chunkLen + 1) & ~1);
|
||||
if(!com.strncmp( iff_dataPtr, name, 4 ))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FindChunk
|
||||
=================
|
||||
*/
|
||||
static void S_FindChunk( const char *name )
|
||||
{
|
||||
iff_lastChunk = iff_data;
|
||||
S_FindNextChunk( name );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_LoadWAV
|
||||
=================
|
||||
*/
|
||||
static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
|
||||
{
|
||||
byte *buffer, *out;
|
||||
int length, samples;
|
||||
|
||||
buffer = FS_LoadFile( name, &length );
|
||||
if( !buffer ) return false;
|
||||
|
||||
iff_data = buffer;
|
||||
iff_end = buffer + length;
|
||||
|
||||
// dind "RIFF" chunk
|
||||
S_FindChunk( "RIFF" );
|
||||
if( !( iff_dataPtr && !com.strncmp( iff_dataPtr + 8, "WAVE", 4 )))
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: missing 'RIFF/WAVE' chunks (%s)\n", name );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
// get "fmt " chunk
|
||||
iff_data = iff_dataPtr + 12;
|
||||
S_FindChunk( "fmt " );
|
||||
if( !iff_dataPtr )
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: missing 'fmt ' chunk (%s)\n", name );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
iff_dataPtr += 8;
|
||||
if( S_GetLittleShort() != 1 )
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: microsoft PCM format only (%s)\n", name );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
info->channels = S_GetLittleShort();
|
||||
if( info->channels != 1 )
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: only mono WAV files supported (%s)\n", name );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
info->rate = S_GetLittleLong();
|
||||
iff_dataPtr += 4+2;
|
||||
|
||||
info->width = S_GetLittleShort() / 8;
|
||||
if( info->width != 1 && info->width != 2 )
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: only 8 and 16 bit WAV files supported (%s)\n", name );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
// get cue chunk
|
||||
S_FindChunk( "cue " );
|
||||
if( iff_dataPtr )
|
||||
{
|
||||
iff_dataPtr += 32;
|
||||
info->loopstart = S_GetLittleLong();
|
||||
S_FindNextChunk( "LIST" ); // if the next chunk is a LIST chunk, look for a cue length marker
|
||||
if( iff_dataPtr )
|
||||
{
|
||||
if( !com.strncmp((const char *)iff_dataPtr + 28, "mark", 4 ))
|
||||
{
|
||||
// this is not a proper parse, but it works with CoolEdit...
|
||||
iff_dataPtr += 24;
|
||||
info->samples = info->loopstart + S_GetLittleLong(); // samples in loop
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info->loopstart = -1;
|
||||
info->samples = 0;
|
||||
}
|
||||
|
||||
// find data chunk
|
||||
S_FindChunk( "data" );
|
||||
if( !iff_dataPtr )
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: missing 'data' chunk (%s)\n", name );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
iff_dataPtr += 4;
|
||||
samples = S_GetLittleLong() / info->width;
|
||||
|
||||
if( info->samples )
|
||||
{
|
||||
if( samples < info->samples )
|
||||
{
|
||||
MsgDev( D_ERROR, "S_LoadWAV: %s has a bad loop length\n", name );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else info->samples = samples;
|
||||
|
||||
if( info->samples <= 0 )
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: file with %i samples (%s)\n", info->samples, name );
|
||||
Mem_Free( buffer );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load the data
|
||||
*wav = out = Z_Malloc( info->samples * info->width );
|
||||
Mem_Copy( out, buffer + (iff_dataPtr - buffer), info->samples * info->width );
|
||||
Mem_Free( buffer );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_UploadSound
|
||||
=================
|
||||
*/
|
||||
static void S_UploadSound( byte *data, wavinfo_t *info, sfx_t *sfx )
|
||||
{
|
||||
sfxcache_t *sc;
|
||||
size_t size, samples;
|
||||
float stepscale;
|
||||
|
||||
// calculate buffer size
|
||||
stepscale = (float)info->rate / dma.speed;
|
||||
samples = info->samples / stepscale;
|
||||
size = samples * info->width * info->channels;
|
||||
|
||||
sc = sfx->cache = Z_Malloc( size + sizeof( sfxcache_t ));
|
||||
sc->length = info->samples;
|
||||
sc->loopstart = info->loopstart;
|
||||
sc->speed = info->rate;
|
||||
sc->width = info->width;
|
||||
sc->stereo = info->channels;
|
||||
|
||||
S_ResampleSfx( sfx, sc->speed, sc->width, data + info->dataofs );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_CreateDefaultSound
|
||||
=================
|
||||
*/
|
||||
static void S_CreateDefaultSound( byte **wav, wavinfo_t *info )
|
||||
{
|
||||
byte *out;
|
||||
int i;
|
||||
|
||||
info->rate = 22050;
|
||||
info->width = 2;
|
||||
info->channels = 1;
|
||||
info->samples = 11025;
|
||||
|
||||
*wav = out = Z_Malloc( info->samples * info->width );
|
||||
|
||||
if( s_check_errors->integer )
|
||||
{
|
||||
// create 1 kHz tone as default sound
|
||||
for( i = 0; i < info->samples; i++ )
|
||||
((short *)out)[i] = com.sin( i * 0.1f ) * 20000;
|
||||
}
|
||||
else
|
||||
{
|
||||
// create silent sound
|
||||
for( i = 0; i < info->samples; i++ )
|
||||
((short *)out)[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_LoadSound
|
||||
=================
|
||||
*/
|
||||
loadformat_t load_formats[] =
|
||||
{
|
||||
{ "sound/%s.%s", "wav", S_LoadWAV },
|
||||
{ "%s.%s", "wav", S_LoadWAV },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
sfxcache_t *S_LoadSound( sfx_t *sfx )
|
||||
{
|
||||
byte *data;
|
||||
wavinfo_t info;
|
||||
const char *ext;
|
||||
string loadname, path;
|
||||
loadformat_t *format;
|
||||
bool anyformat;
|
||||
|
||||
if( !sfx ) return NULL;
|
||||
if( sfx->name[0] == '*' ) return NULL;
|
||||
if( sfx->cache ) return sfx->cache; // see if still in memory
|
||||
|
||||
// load it from disk
|
||||
ext = FS_FileExtension( sfx->name );
|
||||
anyformat = !com.stricmp( ext, "" ) ? true : false;
|
||||
|
||||
com.strncpy( loadname, sfx->name, sizeof( loadname ));
|
||||
FS_StripExtension( loadname ); // remove extension if needed
|
||||
Mem_Set( &info, 0, sizeof( info ));
|
||||
|
||||
// developer warning
|
||||
if( !anyformat ) MsgDev( D_NOTE, "Note: %s will be loading only with ext .%s\n", loadname, ext );
|
||||
|
||||
// now try all the formats in the selected list
|
||||
for( format = load_formats; format->formatstring; format++ )
|
||||
{
|
||||
if( anyformat || !com.stricmp( ext, format->ext ))
|
||||
{
|
||||
com.sprintf( path, format->formatstring, loadname, format->ext );
|
||||
if( format->loadfunc( path, &data, &info ))
|
||||
goto snd_loaded;
|
||||
}
|
||||
}
|
||||
|
||||
sfx->default_sound = true;
|
||||
MsgDev( D_WARN, "FS_LoadSound: couldn't load %s\n", sfx->name );
|
||||
S_CreateDefaultSound( &data, &info );
|
||||
info.loopstart = -1;
|
||||
|
||||
snd_loaded:
|
||||
|
||||
// load it in
|
||||
S_UploadSound( data, &info, sfx );
|
||||
Mem_Free( data );
|
||||
|
||||
return sfx->cache;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// Load a sound
|
||||
// =======================================================================
|
||||
/*
|
||||
==================
|
||||
S_FindSound
|
||||
|
||||
==================
|
||||
*/
|
||||
sfx_t *S_FindSound( const char *name )
|
||||
{
|
||||
int i;
|
||||
sfx_t *sfx;
|
||||
|
||||
if( !name || !name[0] ) return NULL;
|
||||
|
||||
if( com.strlen( name ) >= MAX_STRING )
|
||||
{
|
||||
MsgDev( D_ERROR, "S_FindSound: sound name too long: %s", name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// see if already loaded
|
||||
for( i = 0; i < s_numSfx; i++ )
|
||||
{
|
||||
sfx = &s_knownSfx[i];
|
||||
|
||||
if( !com.strcmp( sfx->name, name ))
|
||||
{
|
||||
// prolonge registration
|
||||
sfx->registration_sequence = s_registration_sequence;
|
||||
return sfx;
|
||||
}
|
||||
}
|
||||
|
||||
// find a free sfx slot spot
|
||||
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++)
|
||||
{
|
||||
if( !sfx->name[0] ) break; // free spot
|
||||
}
|
||||
if( i == s_numSfx )
|
||||
{
|
||||
if( s_numSfx == MAX_SFX )
|
||||
{
|
||||
MsgDev( D_ERROR, "S_FindName: MAX_SFX limit exceeded\n" );
|
||||
return NULL;
|
||||
}
|
||||
s_numSfx++;
|
||||
}
|
||||
|
||||
sfx = &s_knownSfx[i];
|
||||
Mem_Set( sfx, 0, sizeof( *sfx ));
|
||||
com.strncpy( sfx->name, name, MAX_STRING );
|
||||
sfx->registration_sequence = s_registration_sequence;
|
||||
|
||||
return sfx;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
S_BeginRegistration
|
||||
|
||||
=====================
|
||||
*/
|
||||
void S_BeginRegistration( void )
|
||||
{
|
||||
s_registration_sequence++;
|
||||
s_registering = true;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
S_EndRegistration
|
||||
|
||||
=====================
|
||||
*/
|
||||
void S_EndRegistration( void )
|
||||
{
|
||||
sfx_t *sfx;
|
||||
int i;
|
||||
|
||||
// free any sounds not from this registration sequence
|
||||
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
|
||||
{
|
||||
if( !sfx->name[0] ) continue;
|
||||
if( sfx->registration_sequence != s_registration_sequence )
|
||||
{
|
||||
// don't need this sound
|
||||
if( sfx->cache ) Mem_Free( sfx->cache );
|
||||
Mem_Set( sfx, 0, sizeof( *sfx ));
|
||||
}
|
||||
}
|
||||
|
||||
// load everything in
|
||||
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
|
||||
{
|
||||
if( !sfx->name[0] ) continue;
|
||||
S_LoadSound( sfx );
|
||||
}
|
||||
s_registering = false;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
S_RegisterSound
|
||||
|
||||
==================
|
||||
*/
|
||||
sound_t S_RegisterSound( const char *name )
|
||||
{
|
||||
sfx_t *sfx;
|
||||
|
||||
if( !sound_started )
|
||||
return -1;
|
||||
|
||||
sfx = S_FindSound( name );
|
||||
if( !sfx ) return -1;
|
||||
|
||||
sfx->registration_sequence = s_registration_sequence;
|
||||
if( !s_registering ) S_LoadSound( sfx );
|
||||
|
||||
return sfx - s_knownSfx;
|
||||
}
|
||||
|
||||
sfx_t *S_GetSfxByHandle( sound_t handle )
|
||||
{
|
||||
if( handle < 0 || handle >= s_numSfx )
|
||||
{
|
||||
MsgDev( D_ERROR, "S_GetSfxByHandle: handle %i out of range (%i)\n", handle, s_numSfx );
|
||||
return NULL;
|
||||
}
|
||||
return &s_knownSfx[handle];
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FreeSounds
|
||||
=================
|
||||
*/
|
||||
void S_FreeSounds( void )
|
||||
{
|
||||
sfx_t *sfx;
|
||||
int i;
|
||||
|
||||
// stop all sounds
|
||||
S_StopAllSounds();
|
||||
|
||||
// free all sounds
|
||||
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
|
||||
{
|
||||
if( !sfx->name[0] ) continue;
|
||||
if( sfx->cache ) Mem_Free( sfx->cache );
|
||||
Mem_Set( sfx, 0, sizeof( *sfx ));
|
||||
}
|
||||
|
||||
Mem_Set( s_knownSfx, 0, sizeof(s_knownSfx));
|
||||
s_numSfx = 0;
|
||||
}
|
|
@ -0,0 +1,748 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2009 ©
|
||||
// s_main.c - sound engine
|
||||
//=======================================================================
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
// only begin attenuating sound volumes when outside the FULLVOLUME range
|
||||
#define SOUND_FULLVOLUME 80
|
||||
#define SOUND_LOOPATTENUATE 0.003
|
||||
#define MAX_PLAYSOUNDS 128
|
||||
|
||||
dma_t dma;
|
||||
channel_t channels[MAX_CHANNELS];
|
||||
bool sound_started = false;
|
||||
vec3_t listener_origin;
|
||||
vec3_t listener_velocity;
|
||||
vec3_t listener_forward;
|
||||
vec3_t listener_right;
|
||||
vec3_t listener_up;
|
||||
|
||||
int s_framecount; // for autosounds checking
|
||||
int s_clientnum; // cl.playernum + 1
|
||||
int soundtime; // sample PAIRS
|
||||
int paintedtime; // sample PAIRS
|
||||
byte *sndpool;
|
||||
|
||||
playsound_t s_playsounds[MAX_PLAYSOUNDS];
|
||||
playsound_t s_freeplays;
|
||||
playsound_t s_pendingplays;
|
||||
int s_beginofs;
|
||||
|
||||
cvar_t *host_sound;
|
||||
cvar_t *s_check_errors;
|
||||
cvar_t *s_volume;
|
||||
cvar_t *s_testsound;
|
||||
cvar_t *s_loadas8bit;
|
||||
cvar_t *s_khz;
|
||||
cvar_t *s_show;
|
||||
cvar_t *s_mixahead;
|
||||
cvar_t *s_primary;
|
||||
cvar_t *s_pause;
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
SOUNDS PROCESSING
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
/*
|
||||
=================
|
||||
S_PickChannel
|
||||
=================
|
||||
*/
|
||||
channel_t *S_PickChannel( int entnum, int channel )
|
||||
{
|
||||
int i;
|
||||
int firstToDie = -1;
|
||||
int oldestTime = 0x7fffffff;
|
||||
channel_t *ch;
|
||||
|
||||
if( entnum < 0 || channel < 0 ) return NULL; // invalid channel or entnum
|
||||
|
||||
for( i = 0, ch = channels; i < MAX_CHANNELS; i++, ch++ )
|
||||
{
|
||||
// check if this channel is active
|
||||
if( channel == CHAN_AUTO && !ch->sfx )
|
||||
{
|
||||
// free channel
|
||||
firstToDie = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// channel 0 never overrides
|
||||
if( channel != CHAN_AUTO && ( ch->entnum == entnum && ch->entchannel == channel ))
|
||||
{
|
||||
// always override sound from same entity
|
||||
firstToDie = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// don't let monster sounds override player sounds
|
||||
if( entnum != s_clientnum && ch->entnum == s_clientnum && ch->sfx )
|
||||
continue;
|
||||
|
||||
// replace the oldest sound
|
||||
if( ch->end - paintedtime < oldestTime )
|
||||
{
|
||||
oldestTime = ch->end - paintedtime;
|
||||
firstToDie = i;
|
||||
}
|
||||
}
|
||||
|
||||
if( firstToDie == -1 )
|
||||
return NULL;
|
||||
|
||||
ch = &channels[firstToDie];
|
||||
Mem_Set( ch, 0, sizeof( *ch ));
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_SpatializeOrigin
|
||||
|
||||
Used for spatializing channels and autosounds
|
||||
=================
|
||||
*/
|
||||
void S_SpatializeOrigin( vec3_t pos, vec3_t vel, float master_vol, float dist_mult, int *left_vol, int *right_vol )
|
||||
{
|
||||
float dot;
|
||||
float dist;
|
||||
float lscale, rscale, scale;
|
||||
vec3_t source_vec;
|
||||
vec3_t source_vel;
|
||||
|
||||
// calculate stereo seperation and distance attenuation
|
||||
VectorSubtract( pos, listener_origin, source_vec );
|
||||
VectorCopy( vel, source_vel );
|
||||
|
||||
dist = VectorNormalizeLength( source_vec );
|
||||
dist -= SOUND_FULLVOLUME;
|
||||
if( dist < 0 ) dist = 0; // close enough to be at full volume
|
||||
dist *= dist_mult; // different attenuation levels
|
||||
|
||||
dot = DotProduct( listener_right, source_vec );
|
||||
|
||||
if( dma.channels == 1 || !dist_mult )
|
||||
{
|
||||
// no attenuation = no spatialization
|
||||
rscale = 1.0f;
|
||||
lscale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
rscale = 0.5f * (1.0f + dot);
|
||||
lscale = 0.5f * (1.0f - dot);
|
||||
}
|
||||
|
||||
// add in distance effect
|
||||
scale = (1.0f - dist) * rscale;
|
||||
*right_vol = (int)( master_vol * scale );
|
||||
if( *right_vol < 0 ) *right_vol = 0;
|
||||
|
||||
scale = (1.0f - dist) * lscale;
|
||||
*left_vol = (int)( master_vol * scale );
|
||||
if( *left_vol < 0 ) *left_vol = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_Spatialize
|
||||
=================
|
||||
*/
|
||||
void S_SpatializeChannel( channel_t *ch )
|
||||
{
|
||||
vec3_t position, velocity;
|
||||
|
||||
// anything coming from the view entity will always be full volume
|
||||
if( ch->entnum == s_clientnum || !ch->dist_mult )
|
||||
{
|
||||
ch->leftvol = ch->master_vol;
|
||||
ch->rightvol = ch->master_vol;
|
||||
return;
|
||||
}
|
||||
|
||||
if( ch->fixed_origin )
|
||||
{
|
||||
VectorCopy( ch->origin, position );
|
||||
VectorSet( velocity, 0, 0, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ch->autosound ) si.GetSoundSpatialization( ch->loopnum, position, velocity );
|
||||
else si.GetSoundSpatialization( ch->entnum, position, velocity );
|
||||
}
|
||||
|
||||
S_SpatializeOrigin( position, velocity, ch->master_vol, ch->dist_mult, &ch->leftvol, &ch->rightvol );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AllocPlaysound
|
||||
=================
|
||||
*/
|
||||
playsound_t *S_AllocPlaysound( void )
|
||||
{
|
||||
playsound_t *ps;
|
||||
|
||||
ps = s_freeplays.next;
|
||||
if( ps == &s_freeplays )
|
||||
return NULL; // no free playsounds
|
||||
|
||||
// unlink from freelist
|
||||
ps->prev->next = ps->next;
|
||||
ps->next->prev = ps->prev;
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FreePlaysound
|
||||
=================
|
||||
*/
|
||||
void S_FreePlaysound( playsound_t *ps )
|
||||
{
|
||||
// unlink from channel
|
||||
ps->prev->next = ps->next;
|
||||
ps->next->prev = ps->prev;
|
||||
|
||||
// add to free list
|
||||
ps->next = s_freeplays.next;
|
||||
s_freeplays.next->prev = ps;
|
||||
ps->prev = &s_freeplays;
|
||||
s_freeplays.next = ps;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
S_IssuePlaysound
|
||||
|
||||
Take the next playsound and begin it on the channel
|
||||
This is never called directly by S_Play*, but only
|
||||
by the update loop.
|
||||
===============
|
||||
*/
|
||||
void S_IssuePlaysound( playsound_t *ps )
|
||||
{
|
||||
channel_t *ch;
|
||||
sfxcache_t *sc;
|
||||
|
||||
if( s_show->value ) MsgDev( D_INFO, "Issue %i\n", ps->begin );
|
||||
|
||||
// pick a channel to play on
|
||||
ch = S_PickChannel( ps->entnum, ps->entchannel );
|
||||
if( !ch )
|
||||
{
|
||||
if( ps->sfx->name[0] == '#' ) MsgDev( D_ERROR, "dropped sound %s\n", &ps->sfx->name[1] );
|
||||
else MsgDev( D_ERROR, "dropped sound \"sound/%s\"\n", ps->sfx->name );
|
||||
S_FreePlaysound( ps );
|
||||
return;
|
||||
}
|
||||
|
||||
// spatialize
|
||||
if( ps->attenuation == ATTN_STATIC )
|
||||
ch->dist_mult = ps->attenuation * 0.001;
|
||||
else ch->dist_mult = ps->attenuation * 0.0005;
|
||||
|
||||
ch->master_vol = ps->volume;
|
||||
ch->entnum = ps->entnum;
|
||||
ch->entchannel = ps->entchannel;
|
||||
ch->sfx = ps->sfx;
|
||||
ch->use_loop = ps->use_loop;
|
||||
VectorCopy( ps->origin, ch->origin );
|
||||
ch->fixed_origin = ps->fixed_origin;
|
||||
|
||||
S_SpatializeChannel( ch );
|
||||
|
||||
ch->pos = 0;
|
||||
sc = S_LoadSound( ch->sfx );
|
||||
ch->end = paintedtime + sc->length;
|
||||
|
||||
// free the playsound
|
||||
S_FreePlaysound( ps );
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// Start a sound effect
|
||||
// =======================================================================
|
||||
/*
|
||||
====================
|
||||
S_StartSound
|
||||
|
||||
Validates the parms and ques the sound up
|
||||
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 )
|
||||
{
|
||||
sfxcache_t *sc;
|
||||
int vol, start;
|
||||
playsound_t *ps, *sort;
|
||||
sfx_t *sfx = NULL;
|
||||
float timeofs = 0; // FIXME: implement into network protocol
|
||||
|
||||
if( !sound_started )
|
||||
return;
|
||||
|
||||
sfx = S_GetSfxByHandle( handle );
|
||||
if( !sfx ) return;
|
||||
|
||||
// make sure the sound is loaded
|
||||
sc = S_LoadSound( sfx );
|
||||
if( !sc ) return; // couldn't load the sound's data
|
||||
|
||||
vol = fvol * 255;
|
||||
|
||||
// allocate the playsound_t
|
||||
ps = S_AllocPlaysound();
|
||||
if( !ps )
|
||||
{
|
||||
if( sfx->name[0] == '#' ) MsgDev( D_ERROR, "dropped sound %s\n", &sfx->name[1] );
|
||||
else MsgDev( D_ERROR, "dropped sound \"sound/%s\"\n", sfx->name );
|
||||
return;
|
||||
}
|
||||
|
||||
if( pos )
|
||||
{
|
||||
VectorCopy( pos, ps->origin );
|
||||
ps->fixed_origin = true;
|
||||
}
|
||||
else ps->fixed_origin = false;
|
||||
|
||||
ps->entnum = ent;
|
||||
ps->entchannel = chan;
|
||||
ps->attenuation = attn;
|
||||
ps->use_loop = loop;
|
||||
ps->volume = vol;
|
||||
ps->sfx = sfx;
|
||||
|
||||
// drift s_beginofs
|
||||
start = si.GetServerTime() * 0.001 * dma.speed + s_beginofs;
|
||||
if( start < paintedtime )
|
||||
{
|
||||
start = paintedtime;
|
||||
s_beginofs = start - ( si.GetServerTime() * 0.001 * dma.speed );
|
||||
}
|
||||
else if( start > paintedtime + 0.3 * dma.speed )
|
||||
{
|
||||
start = paintedtime + 0.1 * dma.speed;
|
||||
s_beginofs = start - ( si.GetServerTime() * 0.001 * dma.speed );
|
||||
}
|
||||
else s_beginofs -= 10;
|
||||
|
||||
if( !timeofs ) ps->begin = paintedtime;
|
||||
else ps->begin = start + timeofs * dma.speed;
|
||||
|
||||
// sort into the pending sound list
|
||||
for( sort = s_pendingplays.next; sort != &s_pendingplays && sort->begin < ps->begin; sort = sort->next );
|
||||
|
||||
ps->next = sort;
|
||||
ps->prev = sort->prev;
|
||||
ps->next->prev = ps;
|
||||
ps->prev->next = ps;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
S_StartLocalSound
|
||||
==================
|
||||
*/
|
||||
bool S_StartLocalSound( const char *name, float volume, float pitch, const float *origin )
|
||||
{
|
||||
sound_t sfxHandle;
|
||||
|
||||
if( !sound_started )
|
||||
return false;
|
||||
|
||||
sfxHandle = S_RegisterSound( name );
|
||||
S_StartSound( origin, s_clientnum, CHAN_AUTO, sfxHandle, volume, ATTN_NONE, pitch, false );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
S_ClearBuffer
|
||||
==================
|
||||
*/
|
||||
void S_ClearBuffer( void )
|
||||
{
|
||||
int clear;
|
||||
|
||||
if( !sound_started )
|
||||
return;
|
||||
|
||||
s_rawend = 0;
|
||||
|
||||
if( dma.samplebits == 8 )
|
||||
clear = 0x80;
|
||||
else clear = 0;
|
||||
|
||||
SNDDMA_BeginPainting ();
|
||||
if( dma.buffer ) Mem_Set( dma.buffer, clear, dma.samples * dma.samplebits / 8 );
|
||||
SNDDMA_Submit ();
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
S_StopAllSounds
|
||||
==================
|
||||
*/
|
||||
void S_StopAllSounds( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
if( !sound_started )
|
||||
return;
|
||||
|
||||
// clear all the playsounds
|
||||
Mem_Set( s_playsounds, 0, sizeof( s_playsounds ));
|
||||
s_freeplays.next = s_freeplays.prev = &s_freeplays;
|
||||
s_pendingplays.next = s_pendingplays.prev = &s_pendingplays;
|
||||
|
||||
for( i = 0; i < MAX_PLAYSOUNDS; i++ )
|
||||
{
|
||||
s_playsounds[i].prev = &s_freeplays;
|
||||
s_playsounds[i].next = s_freeplays.next;
|
||||
s_playsounds[i].prev->next = &s_playsounds[i];
|
||||
s_playsounds[i].next->prev = &s_playsounds[i];
|
||||
}
|
||||
|
||||
// clear all the channels
|
||||
Mem_Set( channels, 0, sizeof( channels ));
|
||||
S_ClearBuffer ();
|
||||
|
||||
s_framecount = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
S_AddLoopinSound
|
||||
|
||||
Entities with a ->sound field will generated looped sounds
|
||||
that are automatically started, stopped, and merged together
|
||||
as the entities are sent to the client
|
||||
==================
|
||||
*/
|
||||
bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn )
|
||||
{
|
||||
channel_t *ch;
|
||||
sfx_t *sfx = NULL;
|
||||
int i;
|
||||
|
||||
if( !sound_started )
|
||||
return false;
|
||||
sfx = S_GetSfxByHandle( handle );
|
||||
|
||||
// default looped sound it's terrible :)
|
||||
if( !sfx || sfx->default_sound || !sfx->cache )
|
||||
return false;
|
||||
|
||||
// if this entity is already playing the same sound effect on an
|
||||
// active channel, then simply update it
|
||||
for( i = 0, ch = channels; i < MAX_CHANNELS; i++, ch++ )
|
||||
{
|
||||
if( ch->sfx != sfx ) continue;
|
||||
if( !ch->autosound ) continue;
|
||||
if( ch->loopnum != entnum ) continue;
|
||||
if( ch->loopframe + 1 != s_framecount )
|
||||
continue;
|
||||
|
||||
ch->loopframe = s_framecount;
|
||||
break;
|
||||
}
|
||||
if( i != MAX_CHANNELS )
|
||||
return false;
|
||||
|
||||
// otherwise pick a channel and start the sound effect
|
||||
ch = S_PickChannel( 0, 0 );
|
||||
if( !ch )
|
||||
{
|
||||
MsgDev( D_ERROR, "dropped sound \"sound/%s\"\n", sfx->name );
|
||||
return false;
|
||||
}
|
||||
|
||||
ch->sfx = sfx;
|
||||
ch->use_loop = true; // autosounds never comes from S_StartLocalSound
|
||||
ch->autosound = true; // remove next frame
|
||||
ch->loopnum = entnum;
|
||||
ch->loopframe = s_framecount;
|
||||
ch->fixed_origin = false;
|
||||
ch->dist_mult = ATTN_STATIC * 0.001;
|
||||
ch->pos = paintedtime % sfx->cache->length;
|
||||
ch->end = paintedtime + sfx->cache->length - ch->pos;
|
||||
|
||||
// now we can spatialize channel
|
||||
S_SpatializeChannel( ch );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void GetSoundtime( void )
|
||||
{
|
||||
static int buffers, oldsamplepos;
|
||||
int samplepos, fullsamples;
|
||||
|
||||
fullsamples = dma.samples / dma.channels;
|
||||
|
||||
// it is possible to miscount buffers
|
||||
// if it has wrapped twice between
|
||||
// calls to S_Update. Oh well.
|
||||
samplepos = SNDDMA_GetDMAPos();
|
||||
|
||||
if( samplepos < oldsamplepos )
|
||||
{
|
||||
buffers++; // buffer wrapped
|
||||
|
||||
if( paintedtime > 0x40000000 )
|
||||
{
|
||||
// time to chop things off to avoid 32 bit limits
|
||||
buffers = 0;
|
||||
paintedtime = fullsamples;
|
||||
|
||||
S_StopAllSounds();
|
||||
}
|
||||
}
|
||||
|
||||
oldsamplepos = samplepos;
|
||||
soundtime = buffers * fullsamples + samplepos / dma.channels;
|
||||
}
|
||||
|
||||
void S_UpdateChannels( void )
|
||||
{
|
||||
uint endtime;
|
||||
int samps;
|
||||
|
||||
if( !sound_started )
|
||||
return;
|
||||
|
||||
SNDDMA_BeginPainting();
|
||||
|
||||
if( !dma.buffer )
|
||||
return;
|
||||
|
||||
// updates DMA time
|
||||
GetSoundtime();
|
||||
|
||||
// check to make sure that we haven't overshot
|
||||
if( paintedtime < soundtime ) paintedtime = soundtime;
|
||||
|
||||
// mix ahead of current position
|
||||
endtime = soundtime + s_mixahead->value * dma.speed;
|
||||
|
||||
// mix to an even submission block size
|
||||
endtime = (endtime + dma.submission_chunk - 1) & ~(dma.submission_chunk - 1);
|
||||
samps = dma.samples >> (dma.channels - 1);
|
||||
if( endtime - soundtime > samps ) endtime = soundtime + samps;
|
||||
|
||||
S_PaintChannels( endtime );
|
||||
SNDDMA_Submit();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
S_Update
|
||||
|
||||
Called once each time through the main loop
|
||||
============
|
||||
*/
|
||||
void S_Update( int clientnum, const vec3_t position, const vec3_t velocity, const vec3_t axis[3], bool clear )
|
||||
{
|
||||
int i, total;
|
||||
channel_t *ch, *combine = NULL;
|
||||
|
||||
if( !sound_started )
|
||||
return;
|
||||
|
||||
// bump frame count
|
||||
s_framecount++;
|
||||
|
||||
// if the loading plaque is up, clear everything
|
||||
// out to make sure we aren't looping a dirty
|
||||
// dma buffer while loading
|
||||
if( s_pause->integer || clear )
|
||||
{
|
||||
S_ClearBuffer();
|
||||
return;
|
||||
}
|
||||
|
||||
// rebuild scale tables if volume is modified
|
||||
if( s_volume->modified ) S_InitScaletable();
|
||||
|
||||
s_clientnum = clientnum;
|
||||
VectorCopy( position, listener_origin );
|
||||
VectorCopy( velocity, listener_velocity );
|
||||
VectorCopy( axis[0], listener_forward );
|
||||
VectorCopy( axis[1], listener_right );
|
||||
VectorCopy( axis[2], listener_up );
|
||||
|
||||
// Add looping sounds
|
||||
si.AddLoopingSounds();
|
||||
|
||||
// update spatialization for dynamic sounds
|
||||
for( i = 0, ch = channels; i < MAX_CHANNELS; i++, ch++ )
|
||||
{
|
||||
if( !ch->sfx ) continue;
|
||||
if( ch->autosound )
|
||||
{
|
||||
if( ch->loopframe != s_framecount )
|
||||
{
|
||||
Mem_Set( ch, 0, sizeof( *ch )); // stopped
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// respatialize channel
|
||||
S_SpatializeChannel( ch );
|
||||
|
||||
if( !ch->leftvol && !ch->rightvol )
|
||||
{
|
||||
Mem_Set( ch, 0, sizeof( *ch )); // not audible
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// debugging output
|
||||
if( s_show->value )
|
||||
{
|
||||
for( i = total = 0, ch = channels; i < MAX_CHANNELS; i++, ch++ )
|
||||
{
|
||||
if( ch->sfx && ( ch->leftvol || ch->rightvol ))
|
||||
{
|
||||
MsgDev( D_INFO, "%3i %3i %s\n", ch->leftvol, ch->rightvol, ch->sfx->name );
|
||||
total++;
|
||||
}
|
||||
}
|
||||
Msg( "----(%i)---- painted: %i\n", total, paintedtime );
|
||||
}
|
||||
|
||||
// mix some sound
|
||||
S_UpdateChannels();
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
console functions
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
void S_Play_f( void )
|
||||
{
|
||||
if( Cmd_Argc() == 1 )
|
||||
{
|
||||
Msg( "Usage: playsound <soundfile>\n" );
|
||||
return;
|
||||
}
|
||||
S_StartLocalSound( Cmd_Argv( 1 ), 1.0f, PITCH_NORM, NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StopSound_f
|
||||
=================
|
||||
*/
|
||||
void S_StopSound_f( void )
|
||||
{
|
||||
S_StopAllSounds();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_SoundInfo_f
|
||||
=================
|
||||
*/
|
||||
void S_SoundInfo_f( void )
|
||||
{
|
||||
if( !sound_started )
|
||||
{
|
||||
Msg( "sound system not started\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Msg( "%5d channel(s)\n", dma.channels );
|
||||
Msg( "%5d samples\n", dma.samples );
|
||||
Msg( "%5d bits/sample\n", dma.samplebits );
|
||||
Msg( "%5d bytes/sec\n", dma.speed );
|
||||
|
||||
MsgDev( D_NOTE, "%5d samplepos\n", dma.samplepos );
|
||||
MsgDev( D_NOTE, "%5d submission_chunk\n", dma.submission_chunk );
|
||||
MsgDev( D_NOTE, "0x%x dma buffer\n", dma.buffer );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
S_Init
|
||||
================
|
||||
*/
|
||||
bool S_Init( void *hInst )
|
||||
{
|
||||
Cmd_ExecuteString( "sndlatch\n" );
|
||||
|
||||
host_sound = Cvar_Get( "host_sound", "1", CVAR_SYSTEMINFO, "enable sound system" );
|
||||
s_volume = Cvar_Get( "s_volume", "0.7", CVAR_ARCHIVE, "sound volume" );
|
||||
s_khz = Cvar_Get( "s_khz", "11", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "output sound frequency" );
|
||||
s_loadas8bit = Cvar_Get( "s_loadas8bit", "1", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "resample all sounds to 8-bit" );
|
||||
s_mixahead = Cvar_Get( "s_mixahead", "0.2", CVAR_ARCHIVE, "how much sound to mix ahead of time" );
|
||||
s_show = Cvar_Get( "s_show", "0", 0, "show playing sounds" );
|
||||
s_testsound = Cvar_Get( "s_testsound", "0", 0, "generate sine 1 khz wave to testing audio subsystem" );
|
||||
s_primary = Cvar_Get( "s_primary", "0", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "use direct primary buffer" );
|
||||
s_check_errors = Cvar_Get( "s_check_errors", "1", CVAR_ARCHIVE, "ignore audio engine errors" );
|
||||
s_pause = Cvar_Get( "paused", "0", 0, "sound engine pause" );
|
||||
|
||||
Cmd_AddCommand( "playsound", S_Play_f, "playing a specified sound file" );
|
||||
Cmd_AddCommand( "stopsound", S_StopSound_f, "stop all sounds" );
|
||||
Cmd_AddCommand( "soundlist", S_SoundList_f, "display loaded sounds" );
|
||||
Cmd_AddCommand( "s_info", S_SoundInfo_f, "print sound system information" );
|
||||
|
||||
if( !host_sound->integer )
|
||||
{
|
||||
MsgDev( D_INFO, "Audio: disabled\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !SNDDMA_Init( hInst ))
|
||||
{
|
||||
MsgDev( D_INFO, "S_Init: sound system can't initialized\n" );
|
||||
return false;
|
||||
}
|
||||
S_InitScaletable();
|
||||
|
||||
sndpool = Mem_AllocPool( "Sound Zone" );
|
||||
sound_started = true;
|
||||
soundtime = 0;
|
||||
paintedtime = 0;
|
||||
|
||||
S_StopAllSounds ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// Shutdown sound engine
|
||||
// =======================================================================
|
||||
void S_Shutdown( void )
|
||||
{
|
||||
Cmd_RemoveCommand( "playsound" );
|
||||
Cmd_RemoveCommand( "stopsound" );
|
||||
Cmd_RemoveCommand( "soundlist" );
|
||||
Cmd_RemoveCommand( "s_info" );
|
||||
|
||||
if( !sound_started ) return;
|
||||
sound_started = false;
|
||||
|
||||
SNDDMA_Shutdown();
|
||||
|
||||
S_FreeSounds();
|
||||
Mem_FreePool( &sndpool );
|
||||
}
|
|
@ -0,0 +1,327 @@
|
|||
/*
|
||||
Copyright (C) 1997-2001 Id Software, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
*/
|
||||
// snd_mix.c -- portable code to mix sounds for snd_dma.c
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
#define PAINTBUFFER_SIZE 2048
|
||||
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
|
||||
int snd_scaletable[32][256];
|
||||
int *snd_p, snd_linear_count, snd_vol;
|
||||
short *snd_out;
|
||||
|
||||
void S_WriteLinearBlastStereo16( void )
|
||||
{
|
||||
int i, val;
|
||||
|
||||
for( i = 0; i < snd_linear_count; i += 2 )
|
||||
{
|
||||
val = snd_p[i]>>8;
|
||||
if( val > 0x7fff ) snd_out[i] = 0x7fff;
|
||||
else if( val < (short)0x8000 )
|
||||
snd_out[i] = (short)0x8000;
|
||||
else snd_out[i] = val;
|
||||
|
||||
val = snd_p[i+1]>>8;
|
||||
if( val > 0x7fff ) snd_out[i+1] = 0x7fff;
|
||||
else if( val < (short)0x8000 )
|
||||
snd_out[i+1] = (short)0x8000;
|
||||
else snd_out[i+1] = val;
|
||||
}
|
||||
}
|
||||
|
||||
void S_TransferStereo16( dword *pbuf, int endtime )
|
||||
{
|
||||
int lpos, lpaintedtime;
|
||||
|
||||
snd_p = (int *)paintbuffer;
|
||||
lpaintedtime = paintedtime;
|
||||
|
||||
while( lpaintedtime < endtime )
|
||||
{
|
||||
// handle recirculating buffer issues
|
||||
lpos = lpaintedtime & ((dma.samples >> 1) - 1);
|
||||
|
||||
snd_out = (short *) pbuf + (lpos << 1);
|
||||
|
||||
snd_linear_count = (dma.samples>>1) - lpos;
|
||||
if( lpaintedtime + snd_linear_count > endtime )
|
||||
snd_linear_count = endtime - lpaintedtime;
|
||||
|
||||
snd_linear_count <<= 1;
|
||||
|
||||
// write a linear blast of samples
|
||||
S_WriteLinearBlastStereo16();
|
||||
|
||||
snd_p += snd_linear_count;
|
||||
lpaintedtime += (snd_linear_count >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
S_TransferPaintBuffer
|
||||
|
||||
===================
|
||||
*/
|
||||
void S_TransferPaintBuffer( int endtime )
|
||||
{
|
||||
int out_idx, count;
|
||||
int step, val;
|
||||
int *p, out_mask;
|
||||
dword *pbuf;
|
||||
|
||||
pbuf = (dword *)dma.buffer;
|
||||
|
||||
if( s_testsound->integer )
|
||||
{
|
||||
int i, count;
|
||||
|
||||
// write a fixed sine wave
|
||||
count = (endtime - paintedtime);
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
paintbuffer[i].left = com.sin(( paintedtime + i ) * 0.1f ) * 20000 * 256;
|
||||
paintbuffer[i].right = paintbuffer[i].left;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( dma.samplebits == 16 && dma.channels == 2 )
|
||||
{
|
||||
// optimized case
|
||||
S_TransferStereo16( pbuf, endtime );
|
||||
}
|
||||
else
|
||||
{
|
||||
// general case
|
||||
p = (int *)paintbuffer;
|
||||
count = (endtime - paintedtime) * dma.channels;
|
||||
out_mask = dma.samples - 1;
|
||||
out_idx = paintedtime * dma.channels & out_mask;
|
||||
step = 3 - dma.channels;
|
||||
|
||||
if( dma.samplebits == 16 )
|
||||
{
|
||||
short *out = (short *)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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
CHANNEL MIXING
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
void S_PaintChannelFrom8( channel_t *ch, sfxcache_t *sc, int count, int offset )
|
||||
{
|
||||
int data;
|
||||
int *lscale, *rscale;
|
||||
byte *sfx;
|
||||
portable_samplepair_t *samp;
|
||||
int i;
|
||||
|
||||
if( ch->leftvol > 255 ) ch->leftvol = 255;
|
||||
if( ch->rightvol > 255 ) ch->rightvol = 255;
|
||||
|
||||
lscale = snd_scaletable[ch->leftvol>>3];
|
||||
rscale = snd_scaletable[ch->rightvol>>3];
|
||||
sfx = (signed char *)sc->data + ch->pos;
|
||||
|
||||
samp = &paintbuffer[offset];
|
||||
|
||||
for( i = 0; i < count; i++, samp++ )
|
||||
{
|
||||
data = sfx[i];
|
||||
samp->left += lscale[data];
|
||||
samp->right += rscale[data];
|
||||
}
|
||||
ch->pos += count;
|
||||
}
|
||||
|
||||
void S_PaintChannelFrom16( channel_t *ch, sfxcache_t *sc, int count, int offset )
|
||||
{
|
||||
int data;
|
||||
int left, right;
|
||||
int leftvol, rightvol;
|
||||
signed short *sfx;
|
||||
portable_samplepair_t *samp;
|
||||
int i;
|
||||
|
||||
leftvol = ch->leftvol * snd_vol;
|
||||
rightvol = ch->rightvol * snd_vol;
|
||||
sfx = (signed short *)sc->data + ch->pos;
|
||||
|
||||
samp = &paintbuffer[offset];
|
||||
|
||||
for( i = 0; i < count; i++, samp++ )
|
||||
{
|
||||
data = sfx[i];
|
||||
left = ( data * leftvol ) >> 8;
|
||||
right = (data * rightvol) >> 8;
|
||||
samp->left += left;
|
||||
samp->right += right;
|
||||
}
|
||||
ch->pos += count;
|
||||
}
|
||||
|
||||
void S_PaintChannels( int endtime )
|
||||
{
|
||||
channel_t *ch;
|
||||
sfxcache_t *sc;
|
||||
playsound_t *ps;
|
||||
int i, end, ltime, count;
|
||||
|
||||
snd_vol = s_volume->value * 256;
|
||||
|
||||
while( paintedtime < endtime )
|
||||
{
|
||||
// if paintbuffer is smaller than DMA buffer
|
||||
end = endtime;
|
||||
if( endtime - paintedtime > PAINTBUFFER_SIZE )
|
||||
end = paintedtime + PAINTBUFFER_SIZE;
|
||||
|
||||
// start any playsounds
|
||||
while( 1 )
|
||||
{
|
||||
ps = s_pendingplays.next;
|
||||
if( ps == &s_pendingplays )
|
||||
break; // no more pending sounds
|
||||
if( ps->begin <= paintedtime )
|
||||
{
|
||||
S_IssuePlaysound( ps );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ps->begin < end ) end = ps->begin; // stop here
|
||||
break;
|
||||
}
|
||||
|
||||
// clear the paint buffer
|
||||
if( s_rawend < paintedtime )
|
||||
{
|
||||
Mem_Set( paintbuffer, 0, (end - paintedtime) * sizeof( portable_samplepair_t ));
|
||||
}
|
||||
else
|
||||
{
|
||||
int stop;
|
||||
|
||||
// copy from the streaming sound source
|
||||
stop = (end < s_rawend) ? end : s_rawend;
|
||||
|
||||
for( i = paintedtime; i < stop; i++ )
|
||||
paintbuffer[i - paintedtime] = s_rawsamples[i & (MAX_RAW_SAMPLES - 1)];
|
||||
|
||||
for( ; i < end; i++ )
|
||||
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;
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// transfer out according to DMA format
|
||||
S_TransferPaintBuffer( end );
|
||||
paintedtime = end;
|
||||
}
|
||||
}
|
||||
|
||||
void S_InitScaletable( void )
|
||||
{
|
||||
int i, j;
|
||||
int scale;
|
||||
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
scale = i * 8 * 256 * s_volume->value;
|
||||
for( j = 0; j < 256; j++ ) snd_scaletable[i][j] = ((signed char)j) * scale;
|
||||
}
|
||||
s_volume->modified = false;
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2009 ©
|
||||
// s_stream.c - sound streaming
|
||||
//=======================================================================
|
||||
|
||||
#include "sound.h"
|
||||
#include "byteorder.h"
|
||||
|
||||
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
||||
int s_rawend;
|
||||
static bg_track_t s_bgTrack;
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartBackgroundTrack
|
||||
=================
|
||||
*/
|
||||
void S_StartBackgroundTrack( const char *introTrack, const char *loopTrack )
|
||||
{
|
||||
if( !sound_started ) return;
|
||||
S_StopBackgroundTrack();
|
||||
|
||||
// start it up
|
||||
com.snprintf( s_bgTrack.introName, sizeof(s_bgTrack.introName), "media/%s.ogg", introTrack);
|
||||
com.snprintf( s_bgTrack.loopName, sizeof(s_bgTrack.loopName), "media/%s.ogg", loopTrack );
|
||||
|
||||
S_StartStreaming();
|
||||
|
||||
// UNDONE: process streaming
|
||||
}
|
||||
|
||||
void S_StopBackgroundTrack( void )
|
||||
{
|
||||
if( !sound_started ) return;
|
||||
|
||||
S_StopStreaming();
|
||||
|
||||
// UNDONE: close background track
|
||||
Mem_Set( &s_bgTrack, 0, sizeof( bg_track_t ));
|
||||
}
|
||||
|
||||
void S_StartStreaming( void )
|
||||
{
|
||||
// UNDONE: allocate static channel for streaimng
|
||||
}
|
||||
|
||||
void S_StopStreaming( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
S_StreamRawSamples
|
||||
|
||||
Cinematic streaming and voice over network
|
||||
============
|
||||
*/
|
||||
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data )
|
||||
{
|
||||
int i, src, dst;
|
||||
float scale;
|
||||
|
||||
if( !sound_started )
|
||||
return;
|
||||
|
||||
if( s_rawend < paintedtime ) s_rawend = paintedtime;
|
||||
scale = (float)rate / dma.speed;
|
||||
|
||||
if( channels == 2 && width == 2 )
|
||||
{
|
||||
if( scale == 1.0f )
|
||||
{
|
||||
// optimized case
|
||||
for( i = 0; i < samples; i++ )
|
||||
{
|
||||
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left = LittleShort(((short *)data)[i*2]) << 8;
|
||||
s_rawsamples[dst].right = LittleShort(((short *)data)[i*2+1]) << 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = src = 0; src < samples; i++ )
|
||||
{
|
||||
src = i * scale;
|
||||
if( src >= samples ) break;
|
||||
|
||||
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left = LittleShort(((short *)data)[src*2]) << 8;
|
||||
s_rawsamples[dst].right = LittleShort(((short *)data)[src*2+1]) << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( channels == 1 && width == 2 )
|
||||
{
|
||||
for( i = src = 0; src < samples; i++ )
|
||||
{
|
||||
src = i * scale;
|
||||
if( src >= samples ) break;
|
||||
|
||||
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left = LittleShort(((short *)data)[src]) << 8;
|
||||
s_rawsamples[dst].right = LittleShort(((short *)data)[src]) << 8;
|
||||
}
|
||||
}
|
||||
else if( channels == 2 && width == 1 )
|
||||
{
|
||||
for( i = src = 0; src < samples; i++ )
|
||||
{
|
||||
src = i * scale;
|
||||
if( src >= samples ) break;
|
||||
|
||||
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left = ((char *)data)[src*2] << 16;
|
||||
s_rawsamples[dst].right = ((char *)data)[src*2+1] << 16;
|
||||
}
|
||||
}
|
||||
else if( channels == 1 && width == 1 )
|
||||
{
|
||||
for( i = src = 0; src < samples; i++ )
|
||||
{
|
||||
src = i * scale;
|
||||
if( src >= samples ) break;
|
||||
|
||||
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
|
||||
s_rawend++;
|
||||
s_rawsamples[dst].left = (((byte *)data)[src]-128) << 16;
|
||||
s_rawsamples[dst].right = (((byte *)data)[src]-128) << 16;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
# Microsoft Developer Studio Project File - Name="snd_dx" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=snd_dx - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "snd_dx.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "snd_dx.mak" CFG="snd_dx - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "snd_dx - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "snd_dx - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "snd_dx - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "..\temp\snd_dx\!release"
|
||||
# PROP Intermediate_Dir "..\temp\snd_dx\!release"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PLATFORM_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /O2 /I "./" /I "../public" /I "../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /opt:nowin98
|
||||
# ADD LINK32 winmm.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libcmt.lib" /opt:nowin98
|
||||
# SUBTRACT LINK32 /profile
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\snd_dx\!release
|
||||
InputPath=\Xash3D\src_main\temp\snd_dx\!release\snd_dx.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\snd_dx.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\snd_dx.dll "D:\Xash3D\bin\snd_dx.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "snd_dx - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\temp\snd_dx\!debug"
|
||||
# PROP Intermediate_Dir "..\temp\snd_dx\!debug"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PLATFORM_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /MDd /W3 /Gm /Gi /GX /ZI /Od /I "./" /I "../public" /I "../common" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /FD /GZ /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x419 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 winmm.lib /nologo /dll /debug /machine:I386 /nodefaultlib:"libcmt.lib" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /incremental:no /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\snd_dx\!debug
|
||||
InputPath=\Xash3D\src_main\temp\snd_dx\!debug\snd_dx.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\snd_dx.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\snd_dx.dll "D:\Xash3D\bin\snd_dx.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "snd_dx - Win32 Release"
|
||||
# Name "snd_dx - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\s_direct.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\s_export.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\s_load.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\s_main.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\s_mix.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\s_stream.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\s_openal.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sound.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
|
@ -0,0 +1,190 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2009 ©
|
||||
// sound.h - sndlib main header
|
||||
//=======================================================================
|
||||
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "launch_api.h"
|
||||
#include "qfiles_ref.h"
|
||||
#include "vsound_api.h"
|
||||
|
||||
extern stdlib_api_t com;
|
||||
extern vsound_imp_t si;
|
||||
extern byte *sndpool;
|
||||
|
||||
#include "mathlib.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int left;
|
||||
int right;
|
||||
} portable_samplepair_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int length;
|
||||
int loopstart;
|
||||
int speed; // not needed, because converted on load?
|
||||
int width;
|
||||
int stereo;
|
||||
byte data[1]; // variable sized
|
||||
} sfxcache_t;
|
||||
|
||||
typedef struct sfx_s
|
||||
{
|
||||
string name;
|
||||
sfxcache_t *cache;
|
||||
|
||||
int registration_sequence;
|
||||
bool default_sound;
|
||||
} sfx_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
|
||||
typedef struct playsound_s
|
||||
{
|
||||
struct playsound_s *prev, *next;
|
||||
sfx_t *sfx;
|
||||
float volume;
|
||||
float attenuation;
|
||||
int entnum;
|
||||
int entchannel;
|
||||
bool fixed_origin; // use origin field instead of entnum's origin
|
||||
bool use_loop;
|
||||
vec3_t origin;
|
||||
uint begin; // begin on this sample
|
||||
} playsound_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int channels;
|
||||
int samples; // mono samples in buffer
|
||||
int submission_chunk; // don't mix less than this #
|
||||
int samplepos; // in mono samples
|
||||
int samplebits;
|
||||
int speed;
|
||||
byte *buffer;
|
||||
} dma_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sfx_t *sfx; // sfx number
|
||||
int leftvol; // 0-255 volume
|
||||
int rightvol; // 0-255 volume
|
||||
int end; // end time in global paintsamples
|
||||
int pos; // sample position in sfx
|
||||
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
|
||||
vec_t dist_mult; // distance multiplier (attenuation/clipK)
|
||||
int master_vol; // 0-255 master volume
|
||||
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
|
||||
} channel_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int rate;
|
||||
int width;
|
||||
int channels;
|
||||
int loopstart;
|
||||
int samples;
|
||||
int dataofs; // chunk starts this many bytes from file start
|
||||
} wavinfo_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string introName;
|
||||
string loopName;
|
||||
bool looping;
|
||||
file_t *file;
|
||||
int start;
|
||||
int rate;
|
||||
uint format;
|
||||
void *vorbisFile;
|
||||
} bg_track_t;
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
||||
SYSTEM SPECIFIC FUNCTIONS
|
||||
|
||||
====================================================================
|
||||
*/
|
||||
#define Host_Error com.error
|
||||
#define Z_Malloc( size ) Mem_Alloc( sndpool, size )
|
||||
|
||||
// initializes cycling through a DMA buffer and returns information on it
|
||||
bool SNDDMA_Init( void *hInst );
|
||||
int SNDDMA_GetDMAPos( void );
|
||||
void SNDDMA_Shutdown( void );
|
||||
void SNDDMA_BeginPainting( void );
|
||||
void SNDDMA_Submit( void );
|
||||
|
||||
//====================================================================
|
||||
|
||||
#define MAX_CHANNELS 64
|
||||
#define MAX_RAW_SAMPLES 8192
|
||||
|
||||
extern channel_t channels[MAX_CHANNELS];
|
||||
extern int paintedtime;
|
||||
extern int s_rawend;
|
||||
extern vec3_t listener_origin;
|
||||
extern vec3_t listener_forward;
|
||||
extern vec3_t listener_right;
|
||||
extern vec3_t listener_up;
|
||||
extern dma_t dma;
|
||||
extern playsound_t s_pendingplays;
|
||||
extern bool sound_started;
|
||||
|
||||
extern cvar_t *s_check_errors;
|
||||
extern cvar_t *s_volume;
|
||||
extern cvar_t *s_nosound;
|
||||
extern cvar_t *s_loadas8bit;
|
||||
extern cvar_t *s_khz;
|
||||
extern cvar_t *s_show;
|
||||
extern cvar_t *s_mixahead;
|
||||
extern cvar_t *s_testsound;
|
||||
extern cvar_t *s_primary;
|
||||
|
||||
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
|
||||
|
||||
void S_InitScaletable( void );
|
||||
sfxcache_t *S_LoadSound( sfx_t *sfx );
|
||||
void S_IssuePlaysound( playsound_t *ps );
|
||||
void S_PaintChannels( int endtime );
|
||||
|
||||
bool S_Init( void *hInst );
|
||||
void S_Shutdown( void );
|
||||
void S_Activate( bool active );
|
||||
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_Update( int entnum, const vec3_t pos, const vec3_t vel, const vec3_t axis[3], bool clear );
|
||||
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 );
|
||||
channel_t *S_PickChannel( int entNum, int entChannel );
|
||||
int S_StartLocalSound( const char *name, float volume, float pitch, const float *org );
|
||||
sfx_t *S_GetSfxByHandle( sound_t handle );
|
||||
void S_StopBackgroundTrack( void );
|
||||
void S_StartStreaming( void );
|
||||
void S_StopStreaming( void );
|
||||
void S_StopAllSounds( void );
|
||||
void S_FreeSounds( void );
|
||||
|
||||
void S_BeginRegistration( void );
|
||||
sound_t S_RegisterSound( const char *sample );
|
||||
void S_EndRegistration( void );
|
||||
|
||||
#endif//SOUND_H
|
8
todo.log
8
todo.log
|
@ -155,6 +155,10 @@ Beta 13.12.09
|
|||
128. fixup sprites lerping OK
|
||||
129. fixup sound orientation OK
|
||||
130. don't show console on changelevel OK
|
||||
131. support for doom3-style parsing
|
||||
131. support for doom3-style materials parsing
|
||||
132. implement SENTENCE_system
|
||||
133. rebuild vsound.dll
|
||||
133. new sound\render system version replacement OK
|
||||
134. dx sound engine complete OK
|
||||
135. implement dsp, lypsync and vox
|
||||
136. re-vision uimenu
|
||||
137. complete rewriting physic.dll
|
||||
|
|
|
@ -443,7 +443,7 @@ void R_TextureList_f( void )
|
|||
|
||||
Msg( "---------------------------------------------------------\n" );
|
||||
Msg( "%i total textures\n", texCount );
|
||||
Msg( "%.2f total megabytes of textures\n", bytes/1048576.0 );
|
||||
Msg( "%s total memory used\n", memprint( bytes ));
|
||||
Msg( "\n" );
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ enum
|
|||
#define FOG_TEXTURE_WIDTH 256
|
||||
#define FOG_TEXTURE_HEIGHT 32
|
||||
|
||||
#define VID_DEFAULTMODE "4"
|
||||
#define VID_DEFAULTMODE "0"
|
||||
|
||||
#define SHADOW_PLANAR 1
|
||||
#define SHADOW_MAPPING 2
|
|
@ -239,7 +239,7 @@ bool R_SetPixelformat( void )
|
|||
size_t gamma_size;
|
||||
byte *savedGamma;
|
||||
|
||||
Sys_LoadLibrary( &opengl_dll ); // load opengl32.dll
|
||||
Sys_LoadLibrary( NULL, &opengl_dll ); // load opengl32.dll
|
||||
if( !opengl_dll.link ) return false;
|
||||
|
||||
glw_state.minidriver = false; // FIXME
|
||||
|
@ -490,6 +490,20 @@ bool R_CreateWindow( int width, int height, bool fullscreen )
|
|||
r_ypos = Cvar_Get( "r_ypos", "22", CVAR_ARCHIVE, "window position by vertical" );
|
||||
x = r_xpos->integer;
|
||||
y = r_ypos->integer;
|
||||
|
||||
// adjust window coordinates if necessary
|
||||
// so that the window is completely on screen
|
||||
if( x < 0 ) x = 0;
|
||||
if( y < 0 ) y = 0;
|
||||
|
||||
if( Cvar_VariableInteger( "r_mode" ) != glConfig.prev_mode )
|
||||
{
|
||||
if((x + w > glw_state.desktopWidth) || (y + h > glw_state.desktopHeight))
|
||||
{
|
||||
x = ( glw_state.desktopWidth - w ) / 2;
|
||||
y = ( glw_state.desktopHeight - h ) / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glw_state.hWnd = CreateWindowEx( exstyle, "Xash Window", wndname, stylebits, x, y, w, h, NULL, NULL, glw_state.hInst, NULL );
|
||||
|
@ -522,13 +536,21 @@ bool R_CreateWindow( int width, int height, bool fullscreen )
|
|||
|
||||
rserr_t R_ChangeDisplaySettings( int vid_mode, bool fullscreen )
|
||||
{
|
||||
int width, height;
|
||||
|
||||
int width, height;
|
||||
HDC hDC;
|
||||
|
||||
R_SaveVideoMode( vid_mode );
|
||||
|
||||
width = r_width->integer;
|
||||
height = r_height->integer;
|
||||
|
||||
// check our desktop attributes
|
||||
hDC = GetDC( GetDesktopWindow() );
|
||||
glw_state.desktopBitsPixel = GetDeviceCaps( hDC, BITSPIXEL );
|
||||
glw_state.desktopWidth = GetDeviceCaps( hDC, HORZRES );
|
||||
glw_state.desktopHeight = GetDeviceCaps( hDC, VERTRES );
|
||||
ReleaseDC( GetDesktopWindow(), hDC );
|
||||
|
||||
// destroy the existing window
|
||||
if( glw_state.hWnd ) R_Free_OpenGL();
|
||||
|
|
@ -1107,6 +1107,10 @@ typedef struct
|
|||
|
||||
HINSTANCE hinstOpenGL; // HINSTANCE for the OpenGL library
|
||||
|
||||
int desktopBitsPixel;
|
||||
int desktopWidth;
|
||||
int desktopHeight;
|
||||
|
||||
bool software; // software emulation uses RB_RenderShader()
|
||||
bool initialized; // OpenGL subsystem started
|
||||
bool minidriver;
|
|
@ -522,8 +522,8 @@ void GL_InitCommands( void )
|
|||
|
||||
r_environment_color = Cvar_Get( "r_environment_color", "128 128 128", CVAR_ARCHIVE, "map environment light color" );
|
||||
r_ignorehwgamma = Cvar_Get( "r_ignorehwgamma", "0", CVAR_ARCHIVE|CVAR_LATCH_VIDEO, "ignore hardware gamma (e.g. not support)" );
|
||||
r_overbrightbits = Cvar_Get( "r_overbrightbits", "1", CVAR_ARCHIVE|CVAR_LATCH_VIDEO, "renderer overbright bits" );
|
||||
r_mapoverbrightbits = Cvar_Get( "r_mapoverbrightbits", "2", CVAR_ARCHIVE|CVAR_LATCH_VIDEO, "current map overbright bits" );
|
||||
r_overbrightbits = Cvar_Get( "r_overbrightbits", "0", CVAR_ARCHIVE|CVAR_LATCH_VIDEO, "renderer overbright bits" );
|
||||
r_mapoverbrightbits = Cvar_Get( "r_mapoverbrightbits", "0", CVAR_ARCHIVE|CVAR_LATCH_VIDEO, "current map overbright bits" );
|
||||
r_vertexbuffers = Cvar_Get( "r_vertexbuffers", "0", CVAR_ARCHIVE, "store vertex data in VBOs" );
|
||||
|
||||
r_detailtextures = Cvar_Get( "r_detailtextures", "1", CVAR_ARCHIVE, "enable or disable detail textures" );
|
|
@ -1,24 +1,24 @@
|
|||
# Microsoft Developer Studio Project File - Name="render" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Project File - Name="vid_gl" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=render - Win32 Release
|
||||
CFG=vid_gl - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "render.mak".
|
||||
!MESSAGE NMAKE /f "vid_gl.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "render.mak" CFG="render - Win32 Release"
|
||||
!MESSAGE NMAKE /f "vid_gl.mak" CFG="vid_gl - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "render - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "render - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "vid_gl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "vid_gl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
|
@ -29,7 +29,7 @@ CPP=cl.exe
|
|||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "render - Win32 Release"
|
||||
!IF "$(CFG)" == "vid_gl - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
|
@ -38,8 +38,8 @@ RSC=rc.exe
|
|||
# PROP BASE Target_Dir "."
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "..\temp\render\!release"
|
||||
# PROP Intermediate_Dir "..\temp\render\!release"
|
||||
# PROP Output_Dir "..\temp\vid_gl\!release"
|
||||
# PROP Intermediate_Dir "..\temp\vid_gl\!release"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir "."
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c
|
||||
|
@ -57,16 +57,16 @@ LINK32=link.exe
|
|||
# ADD LINK32 msvcrt.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /libpath:"../public/libs/"
|
||||
# SUBTRACT LINK32 /debug
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\render\!release
|
||||
InputPath=\Xash3D\src_main\temp\render\!release\render.dll
|
||||
TargetDir=\Xash3D\src_main\temp\vid_gl\!release
|
||||
InputPath=\Xash3D\src_main\temp\vid_gl\!release\vid_gl.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\render.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\render.dll "D:\Xash3D\bin\render.dll"
|
||||
"D:\Xash3D\bin\vid_gl.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\vid_gl.dll "D:\Xash3D\bin\vid_gl.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "render - Win32 Debug"
|
||||
!ELSEIF "$(CFG)" == "vid_gl - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
|
@ -75,8 +75,8 @@ SOURCE="$(InputPath)"
|
|||
# PROP BASE Target_Dir "."
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "..\temp\render\!debug"
|
||||
# PROP Intermediate_Dir "..\temp\render\!debug"
|
||||
# PROP Output_Dir "..\temp\vid_gl\!debug"
|
||||
# PROP Intermediate_Dir "..\temp\vid_gl\!debug"
|
||||
# PROP Ignore_Export_Lib 1
|
||||
# PROP Target_Dir "."
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c
|
||||
|
@ -94,12 +94,12 @@ LINK32=link.exe
|
|||
# ADD LINK32 msvcrtd.lib user32.lib gdi32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /profile /incremental:no /map
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\render\!debug
|
||||
InputPath=\Xash3D\src_main\temp\render\!debug\render.dll
|
||||
TargetDir=\Xash3D\src_main\temp\vid_gl\!debug
|
||||
InputPath=\Xash3D\src_main\temp\vid_gl\!debug\vid_gl.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\render.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\render.dll "D:\Xash3D\bin\render.dll"
|
||||
"D:\Xash3D\bin\vid_gl.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\vid_gl.dll "D:\Xash3D\bin\vid_gl.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
|
@ -107,8 +107,8 @@ SOURCE="$(InputPath)"
|
|||
|
||||
# Begin Target
|
||||
|
||||
# Name "render - Win32 Release"
|
||||
# Name "render - Win32 Debug"
|
||||
# Name "vid_gl - Win32 Release"
|
||||
# Name "vid_gl - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
|
@ -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>
|
|
@ -1,16 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: vsound - Win32 Debug--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
vsound.dll - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
16
xash.dsw
16
xash.dsw
|
@ -87,7 +87,7 @@ Package=<4>
|
|||
|
||||
###############################################################################
|
||||
|
||||
Project: "render"=".\render\render.dsp" - Package Owner=<4>
|
||||
Project: "vid_gl"=".\vid_gl\vid_gl.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
|
@ -111,7 +111,19 @@ Package=<4>
|
|||
|
||||
###############################################################################
|
||||
|
||||
Project: "vsound"=".\vsound\vsound.dsp" - Package Owner=<4>
|
||||
Project: "snd_al"=".\snd_al\snd_al.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "snd_dx"=".\snd_dx\snd_dx.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
|
|
|
@ -73,7 +73,7 @@ void LeakFile( tree_t *tree )
|
|||
MsgDev( D_NOTE, "--- LeakFile ---\n" );
|
||||
|
||||
// write the points to the file
|
||||
com.sprintf( filename, "%s.lin", source );
|
||||
com.sprintf( filename, "maps/%s.lin", source );
|
||||
linefile = FS_Open( filename, "w" );
|
||||
if( !linefile ) Sys_Error( "couldn't open %s\n", filename );
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ void InitCommon( const int argc, const char **argv )
|
|||
PrepareBSPModel( (int)argc, (char **)argv );
|
||||
break;
|
||||
case HOST_QCCLIB:
|
||||
Sys_LoadLibrary( &vprogs_dll ); // load qcclib
|
||||
Sys_LoadLibrary( NULL, &vprogs_dll ); // load qcclib
|
||||
CreateVprogs = (void *)vprogs_dll.main;
|
||||
PRVM = CreateVprogs( &com, NULL ); // second interface not allowed
|
||||
|
||||
|
|
|
@ -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>
|
Reference in New Issue