03 Oct 2009

This commit is contained in:
g-cont 2009-10-03 00:00:00 +04:00 committed by Alibek Omarov
parent aef0afadfc
commit 3ac2a6e3ec
96 changed files with 3585 additions and 577 deletions

View File

@ -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

View File

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

View File

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

View File

@ -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;
}

View File

@ -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!

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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 );

View File

@ -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 );

View File

@ -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 )

View File

@ -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;
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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;

View File

@ -2329,6 +2329,8 @@ pfnIndexOfEdict
*/
int pfnIndexOfEdict( const edict_t *pEdict )
{
if( !pEdict || pEdict->free )
return 0;
return NUM_FOR_EDICT( pEdict );
}

View File

@ -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" ))

View File

@ -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;

View File

@ -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];

View File

@ -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 ))

View File

@ -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" );

View File

@ -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 );

View File

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

View File

@ -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;
}

View File

@ -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;

View File

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

View File

@ -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

View File

@ -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

View File

@ -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!

View File

@ -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

View File

@ -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();
}

View File

@ -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;

View File

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

View File

@ -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;

View File

@ -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" );

View File

@ -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 )
{

View File

@ -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"

View File

@ -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 );

743
snd_dx/s_direct.c Normal file
View File

@ -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();
}
}

52
snd_dx/s_export.c Normal file
View File

@ -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;
}

609
snd_dx/s_load.c Normal file
View File

@ -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;
}

748
snd_dx/s_main.c Normal file
View File

@ -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 );
}

327
snd_dx/s_mix.c Normal file
View File

@ -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;
}

135
snd_dx/s_stream.c Normal file
View File

@ -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;
}
}
}

153
snd_dx/snd_dx.dsp Normal file
View File

@ -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

190
snd_dx/sound.h Normal file
View File

@ -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

View File

@ -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

View File

@ -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" );
}

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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" );

View File

@ -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"

View File

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

View File

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

View File

@ -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>
{{{

View File

@ -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 );

View File

@ -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

View File

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