13 Jun 2008
This commit is contained in:
parent
ec93bac8e6
commit
89f509dccd
|
@ -19,6 +19,7 @@ render\
|
|||
imglib\
|
||||
ripper\
|
||||
vprogs\
|
||||
vsound\
|
||||
common\
|
||||
common\bsplib
|
||||
common\roqlib
|
||||
|
|
|
@ -35,6 +35,9 @@ 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%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
if "%BUILD_ERROR%"=="" goto build_ok
|
||||
|
||||
echo *********************
|
||||
|
@ -63,9 +66,10 @@ if exist physic\physic.plg del /f /q physic\physic.plg
|
|||
if exist render\render.plg del /f /q render\render.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
|
||||
|
||||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
cd D:\Xash3D\
|
||||
quake.exe -log -game tmpQuArK -debug -dev 3 +map qctest
|
||||
quake.exe -log -game tmpQuArK -debug -dev 3 +map start
|
||||
:done
|
|
@ -19,9 +19,6 @@
|
|||
#define ROQ_PACKET 0x1030
|
||||
#define ZA_SOUND_MONO 0x1020
|
||||
#define ZA_SOUND_STEREO 0x1021
|
||||
extern int s_paintedtime;
|
||||
extern int s_soundtime; // sample PAIRS
|
||||
extern int s_rawend;
|
||||
|
||||
static void RoQ_init( void );
|
||||
static long ROQ_YY_tab[256];
|
||||
|
@ -983,7 +980,7 @@ redump:
|
|||
if (!cinTable.silent)
|
||||
{
|
||||
ssize = RllDecodeMonoToStereo( framedata, sbuf, cinTable.RoQFrameSize, 0, (word)cinTable.roq_flags);
|
||||
S_RawSamples( ssize, 22050, 2, 1, (byte *)sbuf, s_volume->value );
|
||||
S_RawSamples( ssize, 22050, 2, 1, (byte *)sbuf );
|
||||
}
|
||||
break;
|
||||
case ZA_SOUND_STEREO:
|
||||
|
@ -991,11 +988,10 @@ redump:
|
|||
{
|
||||
if (cinTable.numQuads == -1)
|
||||
{
|
||||
S_Update();
|
||||
s_rawend = s_soundtime;
|
||||
//S_Update();
|
||||
}
|
||||
ssize = RllDecodeStereoToStereo( framedata, sbuf, cinTable.RoQFrameSize, 0, (word)cinTable.roq_flags);
|
||||
S_RawSamples( ssize, 22050, 2, 2, (byte *)sbuf, s_volume->value );
|
||||
S_RawSamples( ssize, 22050, 2, 2, (byte *)sbuf );
|
||||
}
|
||||
break;
|
||||
case ROQ_QUAD_INFO:
|
||||
|
@ -1230,8 +1226,6 @@ bool CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemB
|
|||
|
||||
M_ForceMenuOff();
|
||||
Con_Close();
|
||||
|
||||
s_rawend = s_soundtime;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1347,6 +1341,7 @@ bool SCR_PlayCinematic( char *name, int bits )
|
|||
SCR_StopCinematic();
|
||||
|
||||
S_StopAllSounds();
|
||||
S_StartStreaming();
|
||||
|
||||
if (CIN_PlayCinematic( name, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, bits ))
|
||||
{
|
||||
|
|
|
@ -918,3 +918,82 @@ void CL_GetEntitySoundOrigin (int ent, vec3_t org)
|
|||
|
||||
// FIXME: bmodel issues...
|
||||
}
|
||||
|
||||
//
|
||||
// sound engine implementation
|
||||
//
|
||||
|
||||
void CL_GetEntitySoundSpatialization( int ent, vec3_t origin, vec3_t velocity )
|
||||
{
|
||||
centity_t *cent;
|
||||
cmodel_t *cmodel;
|
||||
vec3_t midPoint;
|
||||
|
||||
if( ent < 0 || ent >= MAX_EDICTS )
|
||||
{
|
||||
MsgDev( D_ERROR, "CL_GetEntitySoundSpatialization: invalid entnum", ent );
|
||||
VectorCopy( vec3_origin, origin );
|
||||
VectorCopy( vec3_origin, velocity );
|
||||
return;
|
||||
}
|
||||
|
||||
cent = &cl_entities[ent];
|
||||
|
||||
if( cent->current.renderfx & (RF_FRAMELERP|RF_BEAM))
|
||||
{
|
||||
// calculate origin
|
||||
origin[0] = cent->current.old_origin[0] + (cent->current.origin[0] - cent->current.old_origin[0]) * cl.lerpfrac;
|
||||
origin[1] = cent->current.old_origin[1] + (cent->current.origin[1] - cent->current.old_origin[1]) * cl.lerpfrac;
|
||||
origin[2] = cent->current.old_origin[2] + (cent->current.origin[2] - cent->current.old_origin[2]) * cl.lerpfrac;
|
||||
|
||||
// calculate velocity
|
||||
VectorSubtract( cent->current.origin, cent->current.old_origin, velocity );
|
||||
VectorScale(velocity, 10, velocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
// calculate origin
|
||||
origin[0] = cent->prev.origin[0] + (cent->current.origin[0] - cent->prev.origin[0]) * cl.lerpfrac;
|
||||
origin[1] = cent->prev.origin[1] + (cent->current.origin[1] - cent->prev.origin[1]) * cl.lerpfrac;
|
||||
origin[2] = cent->prev.origin[2] + (cent->current.origin[2] - cent->prev.origin[2]) * cl.lerpfrac;
|
||||
|
||||
// calculate velocity
|
||||
VectorSubtract(cent->current.origin, cent->prev.origin, velocity);
|
||||
VectorScale(velocity, 10, velocity);
|
||||
}
|
||||
|
||||
// if a brush model, offset the origin
|
||||
if( cent->current.solid == SOLID_BMODEL )
|
||||
{
|
||||
cmodel = cl.model_clip[cent->current.modelindex];
|
||||
if(!cmodel) return;
|
||||
VectorAverage(cmodel->mins, cmodel->maxs, midPoint);
|
||||
VectorAdd(origin, midPoint, origin);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AddLoopingSounds
|
||||
|
||||
Entities with a sound field will generate looping sounds that are
|
||||
automatically started and stopped as the entities are sent to the
|
||||
client
|
||||
=================
|
||||
*/
|
||||
void CL_AddLoopingSounds( void )
|
||||
{
|
||||
entity_state_t *ent;
|
||||
int num, i;
|
||||
|
||||
if( cl_paused->value ) return;
|
||||
if( cls.state != ca_active ) return;
|
||||
//if( !cl.sound_prepped ) return;
|
||||
|
||||
for( i = 0; i < cl.frame.num_entities; i++ )
|
||||
{
|
||||
num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
|
||||
ent = &cl_parse_entities[num];
|
||||
se->AddLoopingSound( ent->number, cl.sound_precache[ent->soundindex], 1.0f, ATTN_IDLE );
|
||||
}
|
||||
}
|
|
@ -198,6 +198,10 @@ void CL_Drop (void)
|
|||
CL_Disconnect();
|
||||
}
|
||||
|
||||
float CL_GetTime( void )
|
||||
{
|
||||
return cl.time;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
|
@ -832,21 +836,6 @@ void CL_Userinfo_f (void)
|
|||
Info_Print (Cvar_Userinfo());
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_Snd_Restart_f
|
||||
|
||||
Restart the sound subsystem so it can pick up
|
||||
new parameters and flush all sounds
|
||||
=================
|
||||
*/
|
||||
void CL_Snd_Restart_f (void)
|
||||
{
|
||||
S_Shutdown();
|
||||
S_Init();
|
||||
CL_RegisterSounds();
|
||||
}
|
||||
|
||||
int precache_check; // for autodownload of precache items
|
||||
int precache_spawncount;
|
||||
int precache_tex;
|
||||
|
@ -1086,6 +1075,8 @@ void CL_RequestNextDownload (void)
|
|||
//ZOID
|
||||
CL_RegisterSounds();
|
||||
CL_PrepRefresh();
|
||||
|
||||
if( cls.demoplayback ) return; // not really connected
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_WriteString( &cls.netchan.message, va("begin %i\n", precache_spawncount));
|
||||
}
|
||||
|
@ -1193,8 +1184,6 @@ void CL_InitLocal (void)
|
|||
Cmd_AddCommand ("pingservers", CL_PingServers_f, "send a broadcast packet" );
|
||||
|
||||
Cmd_AddCommand ("userinfo", CL_Userinfo_f, "print current client userinfo" );
|
||||
Cmd_AddCommand ("snd_restart", CL_Snd_Restart_f, "restart sound system" );
|
||||
|
||||
Cmd_AddCommand ("changing", CL_Changing_f, "sent by server to tell client to wait for level change" );
|
||||
Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server" );
|
||||
Cmd_AddCommand ("record", CL_Record_f, "record a demo" );
|
||||
|
@ -1421,8 +1410,7 @@ void CL_Frame( float time )
|
|||
SCR_UpdateScreen();
|
||||
|
||||
// update audio
|
||||
S_Update();
|
||||
S_Respatialize( cl.playernum + 1, cl.refdef.vieworg, cl.v_forward, cl.v_left, cl.v_up );
|
||||
S_Update( cl.playernum + 1, cl.refdef.vieworg, vec3_origin, cl.v_forward, cl.v_up );
|
||||
|
||||
// advance local effects for next frame
|
||||
CL_RunDLights ();
|
||||
|
@ -1442,7 +1430,7 @@ void CL_Frame( float time )
|
|||
CL_Init
|
||||
====================
|
||||
*/
|
||||
void CL_Init (void)
|
||||
void CL_Init( void )
|
||||
{
|
||||
if (dedicated->value) return; // nothing running on the client
|
||||
|
||||
|
@ -1462,7 +1450,6 @@ void CL_Init (void)
|
|||
|
||||
SCR_Init();
|
||||
CL_InitLocal();
|
||||
S_ClearLoopingSounds( true );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -591,7 +591,7 @@ void CL_ParseAmbientSound( sizebuf_t *msg )
|
|||
loopSoundHandle = S_RegisterSound( cl.configstrings[CS_SOUNDS + soundNum] );
|
||||
|
||||
// add ambient looping sound
|
||||
S_AddRealLoopingSound( entityNum, ambient_org, vec3_origin, loopSoundHandle );
|
||||
// S_AddRealLoopingSound( entityNum, ambient_org, vec3_origin, loopSoundHandle );
|
||||
}
|
||||
|
||||
void SHOWNET( sizebuf_t *msg, char *s )
|
||||
|
|
|
@ -512,11 +512,17 @@ void CL_ParseTEnt( sizebuf_t *msg )
|
|||
// impact sound
|
||||
cnt = rand()&15;
|
||||
if (cnt == 1)
|
||||
{
|
||||
S_StartSound (pos, 0, 0, cl_sfx_ric1);
|
||||
}
|
||||
else if (cnt == 2)
|
||||
{
|
||||
S_StartSound (pos, 0, 0, cl_sfx_ric2);
|
||||
}
|
||||
else if (cnt == 3)
|
||||
{
|
||||
S_StartSound (pos, 0, 0, cl_sfx_ric3);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -623,9 +629,13 @@ void CL_ParseTEnt( sizebuf_t *msg )
|
|||
ex->ent.angles[1] = rand() % 360;
|
||||
CL_ExplosionParticles (pos);
|
||||
if (type == TE_GRENADE_EXPLOSION_WATER)
|
||||
{
|
||||
S_StartSound (pos, 0, 0, cl_sfx_watrexp);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound (pos, 0, 0, cl_sfx_grenexp);
|
||||
}
|
||||
break;
|
||||
|
||||
// RAFAEL
|
||||
|
@ -668,9 +678,13 @@ void CL_ParseTEnt( sizebuf_t *msg )
|
|||
ex->frames = 8;
|
||||
CL_ExplosionParticles (pos); // PMM
|
||||
if (type == TE_ROCKET_EXPLOSION_WATER)
|
||||
{
|
||||
S_StartSound (pos, 0, 0, cl_sfx_watrexp);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound (pos, 0, 0, cl_sfx_rockexp);
|
||||
}
|
||||
break;
|
||||
|
||||
case TE_BFG_EXPLOSION:
|
||||
|
|
|
@ -129,6 +129,7 @@ typedef struct
|
|||
int timeoutcount;
|
||||
|
||||
bool refresh_prepped; // false if on new level or new ref dll
|
||||
bool sound_prepped; // false if on new level or new snd dll
|
||||
bool force_refdef; // vid has changed, so we can't use a paused refdef
|
||||
|
||||
int parse_entities; // index (not anded off) into cl_parse_entities[]
|
||||
|
@ -551,48 +552,29 @@ void CL_FreeClientProgs( void );
|
|||
//
|
||||
// cl_sound.c
|
||||
//
|
||||
void S_Init( void );
|
||||
void S_Shutdown( void );
|
||||
#define S_Shutdown se->Shutdown
|
||||
|
||||
// if origin is NULL, the sound will be dynamically sourced from the entity
|
||||
void S_StartSound( vec3_t origin, int entnum, int entchannel, sound_t sfx );
|
||||
int S_StartLocalSound( const char *name );
|
||||
void S_StartBackgroundTrack( const char *intro, const char *loop );
|
||||
void S_StopBackgroundTrack( void );
|
||||
|
||||
// cinematics and voice-over-network will send raw samples
|
||||
// 1.0 volume will be direct output of source samples
|
||||
void S_RawSamples (int samples, int rate, int width, int channels, const byte *data, float volume);
|
||||
|
||||
// stop all sounds and the background track
|
||||
void S_StopAllSounds( void );
|
||||
|
||||
// all continuous looping sounds must be added before calling S_Update
|
||||
void S_ClearLoopingSounds( bool killall );
|
||||
void S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sound_t sfx );
|
||||
void S_AddRealLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocity, sound_t sfx );
|
||||
void S_StopLoopingSound(int entityNum );
|
||||
#define S_StartStreaming se->StartStreaming
|
||||
#define S_RegisterSound se->RegisterSound
|
||||
#define S_StartSound( a, b, c, d ) se->StartSound( a, b, c, d, 1.0f, ATTN_NORM );
|
||||
#define S_StartLocalSound se->StartLocalSound
|
||||
#define S_StartBackgroundTrack se->StartBackgroundTrack
|
||||
#define S_StopBackgroundTrack se->StopBackgroundTrack
|
||||
#define S_RawSamples se->StreamRawSamples
|
||||
#define S_StopAllSounds se->StopAllSounds
|
||||
|
||||
// recompute the reletive volumes for all running sounds
|
||||
// reletive to the given entityNum / orientation
|
||||
void S_Respatialize( int entityNum, const vec3_t origin, vec3_t v_forward, vec3_t v_left, vec3_t v_up );
|
||||
|
||||
// let the sound system know where an entity currently is
|
||||
void S_UpdateEntityPosition( int entityNum, const vec3_t origin );
|
||||
void S_Update( void );
|
||||
void S_DisableSounds( void );
|
||||
void S_EnableSounds( void );
|
||||
void S_BeginRegistration( void );
|
||||
void S_EndRegistration( void );
|
||||
#define S_Update se->Frame
|
||||
#define S_BeginRegistration se->BeginRegistration
|
||||
#define S_EndRegistration se->EndRegistration
|
||||
|
||||
// RegisterSound will allways return a valid sample, even if it
|
||||
// has to create a placeholder. This prevents continuous filesystem
|
||||
// checks for missing files
|
||||
sound_t S_RegisterSound( const char *sample );
|
||||
void S_DisplayFreeMemory(void);
|
||||
void S_ClearSoundBuffer( void );
|
||||
|
||||
void SNDDMA_Activate( void );
|
||||
void S_UpdateBackgroundTrack( void );
|
||||
|
||||
extern cvar_t *s_volume;
|
||||
extern cvar_t *s_nosound;
|
||||
|
@ -647,6 +629,12 @@ void CL_InitPrediction (void);
|
|||
void CL_PredictMove (void);
|
||||
void CL_CheckPredictionError (void);
|
||||
|
||||
//
|
||||
// cl_ents.c
|
||||
//
|
||||
void CL_GetEntitySoundSpatialization( int ent, vec3_t origin, vec3_t velocity );
|
||||
void CL_AddLoopingSounds( void );
|
||||
|
||||
//
|
||||
// cl_fx.c
|
||||
//
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
extern stdlib_api_t com;
|
||||
extern physic_exp_t *pe;
|
||||
extern vprogs_exp_t *vm;
|
||||
extern vsound_exp_t *se;
|
||||
|
||||
/*
|
||||
==============================================================
|
||||
|
@ -137,7 +138,7 @@ HOST INTERFACE
|
|||
*/
|
||||
typedef enum
|
||||
{
|
||||
HOST_INIT, // initalize operations
|
||||
HOST_INIT = 0, // initalize operations
|
||||
HOST_FRAME, // host running
|
||||
HOST_SHUTDOWN, // shutdown operations
|
||||
HOST_ERROR, // host stopped by error
|
||||
|
@ -179,7 +180,7 @@ typedef struct host_parm_s
|
|||
} host_parm_t;
|
||||
|
||||
extern host_parm_t host;
|
||||
long _stdcall Host_WndProc( HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam);
|
||||
long Host_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam );
|
||||
void Host_Init ( uint funcname, int argc, char **argv );
|
||||
void Host_Main ( void );
|
||||
void Host_Free ( void );
|
||||
|
@ -193,6 +194,7 @@ void Host_Error( const char *error, ... );
|
|||
|
||||
// host dlls managment
|
||||
void Host_FreeRender( void );
|
||||
void Host_SndRestart_f( void );
|
||||
|
||||
// host cmds
|
||||
void Host_Error_f( void );
|
||||
|
@ -365,7 +367,12 @@ enum e_clprint
|
|||
extern byte *zonepool;
|
||||
|
||||
#define Z_Malloc(size) Mem_Alloc( zonepool, size )
|
||||
void CL_GetEntitySoundSpatialization( int ent, vec3_t origin, vec3_t velocity );
|
||||
void SV_Transform( sv_edict_t *ed, matrix4x3 transform );
|
||||
int CL_PMpointcontents( vec3_t point );
|
||||
void CL_AddLoopingSounds( void );
|
||||
void CL_RegisterSounds( void );
|
||||
float CL_GetTime( void );
|
||||
void CL_Drop( void );
|
||||
char *Info_ValueForKey( char *s, char *key );
|
||||
void Info_RemoveKey( char *s, char *key );
|
||||
|
|
|
@ -54,7 +54,7 @@ BSC32=bscmake.exe
|
|||
# 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 /subsystem:windows /machine:I386 /opt:nowin98
|
||||
# ADD LINK32 winmm.lib user32.lib msvcrt.lib ole32.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /opt:nowin98
|
||||
# ADD LINK32 winmm.lib user32.lib msvcrt.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /opt:nowin98
|
||||
# SUBTRACT LINK32 /debug /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\engine\!release
|
||||
|
@ -91,7 +91,7 @@ BSC32=bscmake.exe
|
|||
# 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 /subsystem:windows /debug /machine:I386
|
||||
# ADD LINK32 winmm.lib user32.lib msvcrt.lib ole32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrtd.lib" /pdbtype:sept
|
||||
# ADD LINK32 winmm.lib user32.lib msvcrt.lib /nologo /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrtd.lib" /pdbtype:sept
|
||||
# SUBTRACT LINK32 /incremental:no /map /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\engine\!debug
|
||||
|
@ -174,10 +174,6 @@ SOURCE=.\client\cl_scrn.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_sound.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_tent.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -306,10 +302,6 @@ SOURCE=.\net_msg.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\progdefs.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\uimenu\qmenu.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -322,14 +314,6 @@ SOURCE=.\server\server.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\snd_loc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\sound.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\uimenu\uimenu.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
physic_exp_t *pe;
|
||||
render_exp_t *re;
|
||||
vprogs_exp_t *vm;
|
||||
vsound_exp_t *se;
|
||||
host_parm_t host; // host parms
|
||||
stdlib_api_t com, newcom;
|
||||
|
||||
|
@ -21,6 +22,7 @@ char *buildstring = __TIME__ " " __DATE__;
|
|||
dll_info_t physic_dll = { "physic.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(physic_exp_t) };
|
||||
dll_info_t render_dll = { "render.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(render_exp_t) };
|
||||
dll_info_t vprogs_dll = { "vprogs.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(vprogs_exp_t) };
|
||||
dll_info_t vsound_dll = { "vsound.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(vsound_exp_t) };
|
||||
|
||||
cvar_t *timescale;
|
||||
cvar_t *fixedtime;
|
||||
|
@ -148,16 +150,15 @@ void Host_InitRender( void )
|
|||
// studio callbacks
|
||||
ri.StudioEvent = CL_StudioEvent;
|
||||
ri.ShowCollision = pe->DrawCollision;
|
||||
ri.WndProc = Host_WndProc;
|
||||
|
||||
Sys_LoadLibrary( &render_dll );
|
||||
|
||||
CreateRender = (void *)render_dll.main;
|
||||
re = CreateRender( &newcom, &ri );
|
||||
|
||||
if(!re->Init(GetModuleHandle(NULL), Host_WndProc ))
|
||||
if(!re->Init(GetModuleHandle(NULL)))
|
||||
Sys_Error("VID_InitRender: can't init render.dll\nUpdate your opengl drivers\n");
|
||||
|
||||
CL_Snd_Restart_f();
|
||||
}
|
||||
|
||||
void Host_FreeRender( void )
|
||||
|
@ -172,7 +173,7 @@ void Host_FreeRender( void )
|
|||
|
||||
void Host_InitVprogs( int argc, char **argv )
|
||||
{
|
||||
launch_t CreateVprogs;
|
||||
launch_t CreateVprogs;
|
||||
|
||||
Sys_LoadLibrary( &vprogs_dll );
|
||||
|
||||
|
@ -192,6 +193,36 @@ void Host_FreeVprogs( void )
|
|||
Sys_FreeLibrary( &vprogs_dll );
|
||||
}
|
||||
|
||||
void Host_InitSound( void )
|
||||
{
|
||||
static vsound_imp_t si;
|
||||
launch_t CreateSound;
|
||||
|
||||
// phys callback
|
||||
si.api_size = sizeof(vsound_imp_t);
|
||||
si.GetSoundSpatialization = CL_GetEntitySoundSpatialization;
|
||||
si.PointContents = CL_PMpointcontents;
|
||||
si.AddLoopingSounds = CL_AddLoopingSounds;
|
||||
si.GetClientTime = CL_GetTime;
|
||||
|
||||
Sys_LoadLibrary( &vsound_dll );
|
||||
|
||||
CreateSound = (void *)vsound_dll.main;
|
||||
se = CreateSound( &newcom, &si );
|
||||
|
||||
se->Init( host.hWnd );
|
||||
}
|
||||
|
||||
void Host_FreeSound( void )
|
||||
{
|
||||
if(vsound_dll.link)
|
||||
{
|
||||
se->Shutdown();
|
||||
memset( &se, 0, sizeof(se));
|
||||
}
|
||||
Sys_FreeLibrary( &vsound_dll );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
Host_AbortCurrentFrame
|
||||
|
@ -241,6 +272,21 @@ void Host_VidRestart_f( void )
|
|||
Host_InitRender(); // load it again
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Host_SndRestart_f
|
||||
|
||||
Restart the audio subsystem
|
||||
=================
|
||||
*/
|
||||
void Host_SndRestart_f( void )
|
||||
{
|
||||
Host_FreeSound(); // release vsound.dll
|
||||
Host_InitSound(); // load it again
|
||||
|
||||
CL_RegisterSounds();
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
VID_Init
|
||||
|
@ -251,9 +297,12 @@ void VID_Init( void )
|
|||
scr_width = Cvar_Get("width", "640", 0 );
|
||||
scr_height = Cvar_Get("height", "480", 0 );
|
||||
vid_gamma = Cvar_Get( "vid_gamma", "1", CVAR_ARCHIVE );
|
||||
|
||||
Cmd_AddCommand ("vid_restart", Host_VidRestart_f, "restarts video system" );
|
||||
Cmd_AddCommand ("snd_restart", Host_SndRestart_f, "restarts audio system" );
|
||||
|
||||
Host_InitRender();
|
||||
Host_InitSound();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -297,7 +346,7 @@ Host_WndProc
|
|||
main window procedure
|
||||
====================
|
||||
*/
|
||||
long _stdcall Host_WndProc( HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam)
|
||||
long Host_WndProc( void *hWnd, uint uMsg, uint wParam, long lParam )
|
||||
{
|
||||
int temp = 0;
|
||||
|
||||
|
@ -332,8 +381,8 @@ long _stdcall Host_WndProc( HWND hWnd, uint uMsg, WPARAM wParam, LPARAM lParam)
|
|||
else if(LOWORD(wParam) == WA_INACTIVE) host.state = HOST_NOFOCUS;
|
||||
else host.state = HOST_FRAME;
|
||||
|
||||
if( se ) se->Activate( (host.state == HOST_FRAME) ? true : false );
|
||||
Key_ClearStates(); // FIXME!!!
|
||||
SNDDMA_Activate();
|
||||
|
||||
if( host.state == HOST_FRAME )
|
||||
{
|
||||
|
|
|
@ -239,18 +239,6 @@ typedef enum
|
|||
#define SND_ENT (1<<3) // a short 0-2: channel, 3-12: entity
|
||||
#define SND_OFFSET (1<<4) // a byte, msec offset from frame start
|
||||
|
||||
// sound channels
|
||||
// channel 0 never willingly overrides
|
||||
// other channels (1-7) allways override a playing sound on that channel
|
||||
#define CHAN_AUTO 0
|
||||
#define CHAN_WEAPON 1
|
||||
#define CHAN_VOICE 2
|
||||
#define CHAN_ITEM 3
|
||||
#define CHAN_BODY 4
|
||||
#define CHAN_ANNOUNCER 5 // announcer
|
||||
#define CHAN_NO_PHS_ADD 8 // send to all clients, not just ones in PHS (ATTN 0 will also do this)
|
||||
#define CHAN_RELIABLE 16 // send by reliable message, not datagram
|
||||
|
||||
// 0-compressed fields
|
||||
#define DEFAULT_SOUND_PACKET_VOL 1.0
|
||||
#define DEFAULT_SOUND_PACKET_ATTN 1.0
|
||||
|
|
|
@ -126,6 +126,7 @@ struct sv_entvars_s
|
|||
vec3_t post_angles;
|
||||
vec3_t origin_offset;
|
||||
float ltime;
|
||||
string_t loopsound;
|
||||
float bouncetype;
|
||||
float movetype;
|
||||
float solid;
|
||||
|
|
|
@ -50,7 +50,7 @@ void SV_UpdateEntityState( edict_t *ent)
|
|||
ent->priv.sv->s.renderfx = (int)ent->progs.sv->renderfx; // renderer flags
|
||||
ent->priv.sv->s.alpha = ent->progs.sv->alpha; // alpha value
|
||||
ent->priv.sv->s.animtime = ent->progs.sv->animtime; // auto-animating time
|
||||
ent->priv.sv->s.soundindex = (int)ent->progs.sv->sounds;
|
||||
ent->priv.sv->s.soundindex = ent->progs.sv->loopsound;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -404,7 +404,7 @@ void SV_BuildClientFrame (client_state_t *client)
|
|||
ent = PRVM_EDICT_NUM(e);
|
||||
|
||||
// ignore ents without visible models unless they have an effect
|
||||
if (!ent->progs.sv->modelindex && !ent->progs.sv->effects && !ent->progs.sv->noise3 && !ent->priv.sv->event)
|
||||
if (!ent->progs.sv->modelindex && !ent->progs.sv->effects && !ent->progs.sv->loopsound && !ent->priv.sv->event)
|
||||
continue;
|
||||
|
||||
// ignore if not touching a PV leaf
|
||||
|
@ -430,7 +430,7 @@ void SV_BuildClientFrame (client_state_t *client)
|
|||
{
|
||||
// FIXME: if an ent has a model and a sound, but isn't
|
||||
// in the PVS, only the PHS, clear the model
|
||||
if (ent->progs.sv->noise3) bitvector = clientphs;
|
||||
if (ent->progs.sv->loopsound ) bitvector = clientphs;
|
||||
else bitvector = clientpvs;
|
||||
|
||||
// check individual leafs
|
||||
|
|
|
@ -101,7 +101,7 @@ void SV_CreateBaseline (void)
|
|||
{
|
||||
svent = PRVM_EDICT_NUM(entnum);
|
||||
if (svent->priv.sv->free) continue;
|
||||
if (!svent->progs.sv->modelindex && !svent->progs.sv->noise3 && !svent->progs.sv->effects)
|
||||
if (!svent->progs.sv->modelindex && !svent->progs.sv->loopsound && !svent->progs.sv->effects)
|
||||
continue;
|
||||
svent->priv.sv->serialnumber = entnum;
|
||||
|
||||
|
|
|
@ -1116,6 +1116,7 @@ void PF_inpvs( void )
|
|||
if(!VM_ValidateArgs( "EntitiesInPVS", 2 )) return;
|
||||
pvsent = PRVM_G_EDICT(OFS_PARM0);
|
||||
playeronly = (bool)PRVM_G_FLOAT(OFS_PARM1);
|
||||
chain = (edict_t *)prog->edicts;
|
||||
|
||||
if( playeronly )
|
||||
{
|
||||
|
@ -1162,6 +1163,7 @@ void PF_inphs( void )
|
|||
if(!VM_ValidateArgs( "EntitiesInPHS", 2 )) return;
|
||||
pvsent = PRVM_G_EDICT(OFS_PARM0);
|
||||
playeronly = (bool)PRVM_G_FLOAT(OFS_PARM1);
|
||||
chain = (edict_t *)prog->edicts;
|
||||
|
||||
if( playeronly )
|
||||
{
|
||||
|
@ -1458,7 +1460,9 @@ void PF_ambientsound( void )
|
|||
soundent = PRVM_G_EDICT(OFS_PARM0);
|
||||
samp = PRVM_G_STRING(OFS_PARM1);
|
||||
|
||||
if( soundent ) SV_AmbientSound( soundent, SV_SoundIndex( samp ), 0.0f, 0.0f ); // unused parms
|
||||
// check to see if samp was properly precached
|
||||
if( soundent ) soundent->progs.sv->loopsound = SV_SoundIndex( samp );
|
||||
//SV_AmbientSound( soundent, SV_SoundIndex( samp ), 0.0f, 0.0f ); // unused parms
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1091,7 +1091,7 @@ static void UpdateSoundQualityFunc( void *unused )
|
|||
|
||||
// the text box won't show up unless we do a buffer swap
|
||||
re->EndFrame();
|
||||
CL_Snd_Restart_f();
|
||||
Host_SndRestart_f();
|
||||
}
|
||||
|
||||
void Options_MenuInit( void )
|
||||
|
|
|
@ -16,7 +16,7 @@ void ImageLib_Init ( uint funcname )
|
|||
zonepool = Mem_AllocPool( "ImageLib Pool" );
|
||||
app_name = funcname;
|
||||
|
||||
img_resample_lerp = Cvar_Get( "img_lerping", "1", CVAR_ARCHIVE );
|
||||
img_resample_lerp = Cvar_Get( "img_lerping", "1", CVAR_SYSTEMINFO );
|
||||
}
|
||||
|
||||
void ImageLib_Free ( void )
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// launcher.c - main engine launcher
|
||||
// export.c - main engine launcher
|
||||
//=======================================================================
|
||||
|
||||
#include "launch.h"
|
|
@ -54,15 +54,14 @@ typedef struct mempool_s
|
|||
uint sentinel2; // should always be MEMHEADER_SENTINEL1
|
||||
} mempool_t;
|
||||
|
||||
|
||||
typedef struct memarray_s
|
||||
typedef struct memcluster_s
|
||||
{
|
||||
byte *data;
|
||||
byte *allocflags;
|
||||
size_t numflaggedrecords;
|
||||
} memcluster_t;
|
||||
|
||||
typedef struct memarraypool_s
|
||||
typedef struct memarray_s
|
||||
{
|
||||
byte *mempool;
|
||||
size_t recordsize;
|
||||
|
|
|
@ -944,4 +944,22 @@ bool SC_FilterToken(char *filter, char *name, int casecmp)
|
|||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SC_HashKey
|
||||
|
||||
returns hash key for string
|
||||
=================
|
||||
*/
|
||||
uint SC_HashKey( const char *string, uint hashSize )
|
||||
{
|
||||
uint hashKey = 0;
|
||||
int i;
|
||||
|
||||
for( i = 0; string[i]; i++ )
|
||||
hashKey = (hashKey + i) * 37 + com_tolower(string[i]);
|
||||
|
||||
return (hashKey % hashSize);
|
||||
}
|
|
@ -100,6 +100,7 @@ void Sys_GetStdAPI( void )
|
|||
com.Com_ParseWord = SC_ParseWord; // parse word from char buffer
|
||||
com.Com_Search = FS_Search; // returned list of founded files
|
||||
com.Com_Filter = SC_FilterToken; // compare keyword by mask with filter
|
||||
com.Com_HashKey = SC_HashKey; // returns hash key for a string (generic fucntion)
|
||||
com.com_token = token; // contains current token
|
||||
|
||||
// console variables
|
||||
|
|
|
@ -136,7 +136,7 @@ SOURCE=.\common\filesystem.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\common\launcher.c
|
||||
SOURCE=.\common\export.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
|
|
@ -362,6 +362,7 @@ uint Com_BlockChecksumKey(void *buffer, int length, int key);
|
|||
bool SC_LoadScript( const char *filename, char *buf, int size );
|
||||
bool SC_AddScript( const char *filename, char *buf, int size );
|
||||
bool SC_FilterToken(char *filter, char *name, int casecmp);
|
||||
uint SC_HashKey( const char *string, uint hashSize );
|
||||
bool SC_ParseToken_Simple(const char **data_p);
|
||||
char *SC_ParseToken(const char **data_p );
|
||||
char *SC_ParseWord( const char **data_p );
|
||||
|
|
|
@ -71,6 +71,23 @@
|
|||
|
||||
#define PM_MAXTOUCH 32
|
||||
|
||||
// sound channels
|
||||
#define CHAN_AUTO 0
|
||||
#define CHAN_WEAPON 1
|
||||
#define CHAN_VOICE 2
|
||||
#define CHAN_ITEM 3
|
||||
#define CHAN_BODY 4
|
||||
#define CHAN_ANNOUNCER 5 // announcer
|
||||
// flags
|
||||
#define CHAN_NO_PHS_ADD 8 // Send to all clients, not just ones in PHS (ATTN 0 will also do this)
|
||||
#define CHAN_RELIABLE 16 // Send by reliable message, not datagram
|
||||
|
||||
// Sound attenuation values
|
||||
#define ATTN_NONE 0 // Full volume the entire level
|
||||
#define ATTN_NORM 1
|
||||
#define ATTN_IDLE 2
|
||||
#define ATTN_STATIC 3 // Diminish very rapidly with distance
|
||||
|
||||
// player_state->stats[] indexes
|
||||
enum player_stats
|
||||
{
|
||||
|
@ -355,7 +372,7 @@ typedef struct render_exp_s
|
|||
size_t api_size; // must matched with sizeof(render_exp_t)
|
||||
|
||||
// initialize
|
||||
bool (*Init)( void *hInstance, void *WndProc ); // init all render systems
|
||||
bool (*Init)( void *hInst ); // init all render systems
|
||||
void (*Shutdown)( void ); // shutdown all render systems
|
||||
|
||||
void (*BeginRegistration) (char *map);
|
||||
|
@ -387,7 +404,7 @@ typedef struct render_imp_s
|
|||
// client fundamental callbacks
|
||||
void (*StudioEvent)( mstudioevent_t *event, entity_t *ent );
|
||||
void (*ShowCollision)( cmdraw_t callback ); // debug
|
||||
|
||||
long (*WndProc)( void *hWnd, uint uMsg, uint wParam, long lParam );
|
||||
} render_imp_t;
|
||||
|
||||
/*
|
||||
|
@ -471,7 +488,7 @@ typedef struct physic_imp_s
|
|||
/*
|
||||
==============================================================================
|
||||
|
||||
IMGLIB.DLL INTERFACE
|
||||
VPROGS.DLL INTERFACE
|
||||
==============================================================================
|
||||
*/
|
||||
typedef struct vprogs_exp_s
|
||||
|
@ -525,10 +542,58 @@ typedef struct vprogs_exp_s
|
|||
void (*ExecuteProgram)( func_t fnum, const char *errormessage );
|
||||
void (*Crash)( void ); // crash virtual machine
|
||||
|
||||
prvm_prog_t *prog; // virtual machine state
|
||||
prvm_prog_t *prog; // virtual machine current state
|
||||
|
||||
} vprogs_exp_t;
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
VSOUND.DLL INTERFACE
|
||||
==============================================================================
|
||||
*/
|
||||
typedef struct vsound_exp_s
|
||||
{
|
||||
// interface validator
|
||||
size_t api_size; // must matched with sizeof(vprogs_api_t)
|
||||
|
||||
void (*Init)( void *hInst ); // init host
|
||||
void (*Shutdown)( void ); // close host
|
||||
|
||||
// sound manager
|
||||
void (*BeginRegistration)( void );
|
||||
sound_t (*RegisterSound)( const char *name );
|
||||
void (*EndRegistration)( void );
|
||||
|
||||
void (*StartSound)( const vec3_t pos, int entnum, int channel, sound_t sfx, float vol, float attn );
|
||||
void (*StreamRawSamples)( int samples, int rate, int width, int channels, const byte *data );
|
||||
bool (*AddLoopingSound)( int entnum, sound_t handle, float volume, float attn );
|
||||
bool (*StartLocalSound)( const char *name );
|
||||
void (*StartBackgroundTrack)( const char *introTrack, const char *loopTrack );
|
||||
void (*StopBackgroundTrack)( void );
|
||||
|
||||
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 (*StopAllSounds)( void );
|
||||
void (*FreeSounds)( void );
|
||||
|
||||
void (*Activate)( bool active );
|
||||
|
||||
} vsound_exp_t;
|
||||
|
||||
typedef struct vsound_imp_s
|
||||
{
|
||||
// interface validator
|
||||
size_t api_size; // must matched with sizeof(vsound_imp_t)
|
||||
|
||||
void (*GetSoundSpatialization)( int entnum, vec3_t origin, vec3_t velocity );
|
||||
int (*PointContents)( vec3_t point );
|
||||
void (*AddLoopingSounds)( void );
|
||||
float (*GetClientTime)( void );
|
||||
} vsound_imp_t;
|
||||
|
||||
// this is the only function actually exported at the linker level
|
||||
typedef void *(*launch_t)( stdlib_api_t*, void* );
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#define VectorLength2(a) (DotProduct(a, a))
|
||||
#define VectorDistance(a, b) (sqrt(VectorDistance2(a,b)))
|
||||
#define VectorDistance2(a, b) (((a)[0] - (b)[0]) * ((a)[0] - (b)[0]) + ((a)[1] - (b)[1]) * ((a)[1] - (b)[1]) + ((a)[2] - (b)[2]) * ((a)[2] - (b)[2]))
|
||||
#define VectorAverage(a,b,o) ((o)[0]=((a)[0]+(b)[0])*0.5,(o)[1]=((a)[1]+(b)[1])*0.5,(o)[2]=((a)[2]+(b)[2])*0.5)
|
||||
#define VectorSet(v, x, y, z) {v[0] = x; v[1] = y; v[2] = z;}
|
||||
#define Vector4Set(v, x, y, z, w) {v[0] = x, v[1] = y, v[2] = z, v[3] = w;}
|
||||
#define VectorClear(x) {x[0] = x[1] = x[2] = 0;}
|
||||
|
|
|
@ -93,6 +93,7 @@ typedef struct stdilib_api_s
|
|||
char *(*Com_ParseWord)( const char **data ); // parse word from char buffer
|
||||
search_t *(*Com_Search)(const char *pattern, int casecmp ); // returned list of found files
|
||||
bool (*Com_Filter)(char *filter, char *name, int casecmp ); // compare keyword by mask with filter
|
||||
uint (*Com_HashKey)( const char *string, uint hashSize ); // returns hash key for a string
|
||||
char *com_token; // contains current token
|
||||
|
||||
// console variables
|
||||
|
@ -227,6 +228,7 @@ typedef struct stdilib_api_s
|
|||
#define Com_ParseWord com.Com_ParseWord
|
||||
#define Com_SimpleGetToken com.Com_ParseToken_Simple
|
||||
#define Com_Filter com.Com_Filter
|
||||
#define Com_HashKey com.Com_HashKey
|
||||
#define Com_LoadScript com.Com_LoadScript
|
||||
#define Com_IncludeScript com.Com_AddScript
|
||||
#define Com_ResetScript com.Com_ResetScript
|
||||
|
|
|
@ -35,6 +35,9 @@ 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%
|
||||
if errorlevel 1 set BUILD_ERROR=1
|
||||
|
||||
if "%BUILD_ERROR%"=="" goto build_ok
|
||||
|
||||
echo *********************
|
||||
|
@ -63,6 +66,7 @@ if exist physic\physic.plg del /f /q physic\physic.plg
|
|||
if exist render\render.plg del /f /q render\render.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
|
||||
|
||||
echo Build succeeded!
|
||||
echo Please wait. Xash is now loading
|
||||
|
|
|
@ -310,8 +310,8 @@ extern int registration_sequence;
|
|||
|
||||
void V_AddBlend (float r, float g, float b, float a, float *v_blend);
|
||||
|
||||
int R_Init( void *hinstance, void *hWnd );
|
||||
void R_Shutdown( void );
|
||||
int R_Init( void *hinstance );
|
||||
void R_Shutdown( void );
|
||||
|
||||
void R_RenderView (refdef_t *fd);
|
||||
void R_DrawStudioModel( int passnum );
|
||||
|
@ -505,7 +505,7 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
|
|||
|
||||
void GLimp_BeginFrame( void );
|
||||
void GLimp_EndFrame( void );
|
||||
int GLimp_Init( void *hinstance, void *hWnd );
|
||||
int GLimp_Init( void *hinstance );
|
||||
void GLimp_Shutdown( void );
|
||||
int GLimp_SetMode( int vid_mode, bool fullscreen );
|
||||
void GLimp_AppActivate( bool active );
|
||||
|
|
|
@ -1114,7 +1114,7 @@ bool R_SetMode (void)
|
|||
R_Init
|
||||
===============
|
||||
*/
|
||||
int R_Init( void *hinstance, void *hWnd )
|
||||
int R_Init( void *hinstance )
|
||||
{
|
||||
int j, err;
|
||||
extern float r_turbsin[256];
|
||||
|
@ -1137,7 +1137,7 @@ int R_Init( void *hinstance, void *hWnd )
|
|||
}
|
||||
|
||||
// initialize OS-specific parts of OpenGL
|
||||
if ( !GLimp_Init( hinstance, hWnd ) )
|
||||
if ( !GLimp_Init( hinstance ))
|
||||
{
|
||||
QGL_Shutdown();
|
||||
return false;
|
||||
|
|
|
@ -345,7 +345,7 @@ void GLimp_Shutdown( void )
|
|||
** of OpenGL. Under Win32 this means dealing with the pixelformats and
|
||||
** doing the wgl interface stuff.
|
||||
*/
|
||||
bool GLimp_Init( void *hinstance, void *wndproc )
|
||||
bool GLimp_Init( void *hinstance )
|
||||
{
|
||||
#define OSR2_BUILD_NUMBER 1111
|
||||
|
||||
|
@ -383,7 +383,7 @@ bool GLimp_Init( void *hinstance, void *wndproc )
|
|||
}
|
||||
|
||||
glw_state.hInstance = ( HINSTANCE ) hinstance;
|
||||
glw_state.wndproc = wndproc;
|
||||
glw_state.wndproc = ri.WndProc;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
6
todo.log
6
todo.log
|
@ -20,8 +20,10 @@ fopen
|
|||
7. избавиться от sv.moved_edicts
|
||||
|
||||
Звуковой движок:
|
||||
1. Сделать OpenAL совместимый движок
|
||||
2. Поддержка OGG Vorbis
|
||||
1. Сделать OpenAL совместимый движок OK
|
||||
2. Поддержка OGG Vorbis OK
|
||||
3. Сделать поддержку loop звуков OK
|
||||
4.
|
||||
|
||||
Физика игрока:
|
||||
1. Убрать отскоки от стен
|
||||
|
|
|
@ -23,7 +23,7 @@ extern int prvm_developer;
|
|||
|
||||
#define Host_Error com.error
|
||||
|
||||
#define PROG_CRC_SERVER 406
|
||||
#define PROG_CRC_SERVER 14510
|
||||
#define PROG_CRC_CLIENT 7430
|
||||
#define PROG_CRC_UIMENU 36416
|
||||
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,51 @@
|
|||
//=======================================================================
|
||||
// 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.Init = S_Init;
|
||||
snd.Shutdown = S_Shutdown;
|
||||
|
||||
// sound manager
|
||||
snd.BeginRegistration = S_BeginRegistration;
|
||||
snd.RegisterSound = S_RegisterSound;
|
||||
snd.EndRegistration = S_EndRegistration;
|
||||
|
||||
snd.StartSound = S_StartSound;
|
||||
snd.StreamRawSamples = S_StreamRawSamples;
|
||||
snd.AddLoopingSound = S_AddLoopingSound;
|
||||
snd.StartLocalSound = S_StartLocalSound;
|
||||
snd.StartBackgroundTrack = S_StartBackgroundTrack;
|
||||
snd.StopBackgroundTrack = S_StopBackgroundTrack;
|
||||
|
||||
snd.StartStreaming = S_StartStreaming;
|
||||
snd.StopStreaming = S_StopStreaming;
|
||||
|
||||
snd.Frame = S_Update;
|
||||
snd.StopAllSounds = S_StopAllSounds;
|
||||
snd.FreeSounds = S_FreeSounds;
|
||||
|
||||
snd.Activate = S_Activate;
|
||||
|
||||
return &snd;
|
||||
}
|
|
@ -0,0 +1,490 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// s_load.c - sound managment
|
||||
//=======================================================================
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
#define MAX_SFX 4096
|
||||
static sfx_t s_knownSfx[MAX_SFX];
|
||||
static int s_numSfx = 0;
|
||||
|
||||
#define SFX_HASHSIZE 128
|
||||
static sfx_t *sfxHash[SFX_HASHSIZE];
|
||||
|
||||
/*
|
||||
=================
|
||||
S_SoundList_f
|
||||
=================
|
||||
*/
|
||||
void S_SoundList_f( void )
|
||||
{
|
||||
sfx_t *sfx;
|
||||
int i, samples = 0;
|
||||
|
||||
Msg("\n");
|
||||
Msg(" -samples -hz-- -format- -name--------\n");
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if( sfx->name[0] == '#' ) Msg("%s", &sfx->name[1]);
|
||||
else Msg("sound/%s", sfx->name);
|
||||
|
||||
if( sfx->default_snd ) Msg(" (DEFAULTED)\n");
|
||||
else Msg("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if( sfx->name[0] == '*' ) Msg(" placeholder %s\n", sfx->name);
|
||||
else Msg(" not loaded %s\n", sfx->name);
|
||||
}
|
||||
}
|
||||
|
||||
Msg("-------------------------------------------\n");
|
||||
Msg("%i total samples\n", samples);
|
||||
Msg("%i total sounds\n", s_numSfx);
|
||||
Msg("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
info->samples = S_GetLittleLong() / info->width;
|
||||
|
||||
if( info->samples <= 0 )
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: file with 0 samples (%s)\n", 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, int width, int channels, sfx_t *sfx )
|
||||
{
|
||||
int size;
|
||||
|
||||
// calculate buffer size
|
||||
size = sfx->samples * width * channels;
|
||||
|
||||
// Set buffer format
|
||||
if( width == 2 )
|
||||
{
|
||||
if( channels == 2 ) sfx->format = AL_FORMAT_STEREO16;
|
||||
else sfx->format = AL_FORMAT_MONO16;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( channels == 2 ) sfx->format = AL_FORMAT_STEREO8;
|
||||
else sfx->format = AL_FORMAT_MONO8;
|
||||
}
|
||||
|
||||
// upload the sound
|
||||
palGenBuffers(1, &sfx->bufferNum);
|
||||
palBufferData( sfx->bufferNum, sfx->format, data, size, sfx->rate );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
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 );
|
||||
for( i = 0; i < info->samples; i++ )
|
||||
((short *)out)[i] = sin(i * 0.1f) * 20000;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_LoadSound
|
||||
=================
|
||||
*/
|
||||
bool S_LoadSound( sfx_t *sfx )
|
||||
{
|
||||
string name;
|
||||
byte *data;
|
||||
wavinfo_t info;
|
||||
|
||||
if( !sfx ) return false;
|
||||
if( sfx->name[0] == '*' ) return false;
|
||||
if( sfx->loaded ) return true; // see if still in memory
|
||||
|
||||
// load it from disk
|
||||
if( sfx->name[0] == '#' )
|
||||
com.snprintf( name, sizeof(name), "%s", &sfx->name[1]);
|
||||
else com.snprintf( name, sizeof(name), "sound/%s", sfx->name );
|
||||
|
||||
if(!S_LoadWAV(name, &data, &info))
|
||||
{
|
||||
sfx->default_snd = true;
|
||||
|
||||
MsgWarn( "couldn't find sound '%s', using default...\n", name );
|
||||
S_CreateDefaultSound( &data, &info );
|
||||
}
|
||||
|
||||
// load it in
|
||||
sfx->loaded = true;
|
||||
sfx->samples = info.samples;
|
||||
sfx->rate = info.rate;
|
||||
|
||||
S_UploadSound( data, info.width, info.channels, sfx );
|
||||
Mem_Free(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// Load a sound
|
||||
// =======================================================================
|
||||
/*
|
||||
================
|
||||
return a hash value for the sfx name
|
||||
================
|
||||
*/
|
||||
static long S_HashSFXName( const char *name )
|
||||
{
|
||||
int i = 0;
|
||||
long hash = 0;
|
||||
char letter;
|
||||
|
||||
while( name[i] != '\0' )
|
||||
{
|
||||
letter = com.tolower(name[i]);
|
||||
if (letter =='.') break; // don't include extension
|
||||
if (letter =='\\') letter = '/'; // damn path names
|
||||
hash += (long)(letter)*(i+119);
|
||||
i++;
|
||||
}
|
||||
hash &= (SFX_HASHSIZE-1);
|
||||
return hash;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FindSound
|
||||
=================
|
||||
*/
|
||||
sfx_t *S_FindSound( const char *name )
|
||||
{
|
||||
int i, hash;
|
||||
sfx_t *sfx;
|
||||
|
||||
if( !name || !name[0] )
|
||||
{
|
||||
MsgWarn("S_FindSound: empty name\n");
|
||||
return NULL;
|
||||
}
|
||||
if( com.strlen(name) >= MAX_STRING )
|
||||
{
|
||||
MsgWarn("S_FindSound: sound name too long: %s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash = S_HashSFXName(name);
|
||||
sfx = sfxHash[hash];
|
||||
|
||||
// see if already loaded
|
||||
while( sfx )
|
||||
{
|
||||
if (!stricmp(sfx->name, name))
|
||||
return sfx;
|
||||
sfx = sfx->nextHash;
|
||||
}
|
||||
|
||||
// find a free sfx slot
|
||||
for (i = 0; i < s_numSfx; i++)
|
||||
{
|
||||
if(!s_knownSfx[i].name[0])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == s_numSfx)
|
||||
{
|
||||
if (s_numSfx == MAX_SFX)
|
||||
{
|
||||
MsgWarn("S_FindName: MAX_SFX limit exceeded\n");
|
||||
return NULL;
|
||||
}
|
||||
s_numSfx++;
|
||||
}
|
||||
|
||||
sfx = &s_knownSfx[i];
|
||||
memset (sfx, 0, sizeof(*sfx));
|
||||
strcpy (sfx->name, name);
|
||||
sfx->nextHash = sfxHash[hash];
|
||||
sfxHash[hash] = sfx;
|
||||
|
||||
return sfx;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
S_BeginRegistration
|
||||
=====================
|
||||
*/
|
||||
void S_BeginRegistration( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
S_EndRegistration
|
||||
=====================
|
||||
*/
|
||||
void S_EndRegistration( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_RegisterSound
|
||||
=================
|
||||
*/
|
||||
sound_t S_RegisterSound( const char *name )
|
||||
{
|
||||
sfx_t *sfx;
|
||||
|
||||
if(!al_state.initialized)
|
||||
return 0;
|
||||
|
||||
sfx = S_FindSound( name );
|
||||
S_LoadSound( sfx );
|
||||
|
||||
if( !sfx ) return 0;
|
||||
return sfx - s_knownSfx;
|
||||
}
|
||||
|
||||
sfx_t *S_GetSfxByHandle( sound_t handle )
|
||||
{
|
||||
if( handle < 0 || handle >= s_numSfx )
|
||||
{
|
||||
MsgWarn("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; i < s_numSfx; i++)
|
||||
{
|
||||
sfx = &s_knownSfx[i];
|
||||
palDeleteBuffers(1, &sfx->bufferNum);
|
||||
}
|
||||
|
||||
memset( sfxHash, 0, sizeof(sfx_t *)*SFX_HASHSIZE);
|
||||
memset( s_knownSfx, 0, sizeof(s_knownSfx));
|
||||
|
||||
s_numSfx = 0;
|
||||
}
|
|
@ -0,0 +1,454 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// s_load.c - sound managment
|
||||
//=======================================================================
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
#define SFX_HASHSIZE 256
|
||||
#define MAX_SFX 1024
|
||||
|
||||
static sfx_t *s_sfxHash[SFX_HASHSIZE];
|
||||
static sfx_t *s_sfx[MAX_SFX];
|
||||
static int s_numSfx;
|
||||
|
||||
/*
|
||||
=================
|
||||
S_SoundList_f
|
||||
=================
|
||||
*/
|
||||
void S_SoundList_f( void )
|
||||
{
|
||||
sfx_t *sfx;
|
||||
int i, samples = 0;
|
||||
|
||||
Msg("\n");
|
||||
Msg(" -samples -hz-- -format- -name--------\n");
|
||||
|
||||
for( i = 0; i < s_numSfx; i++ )
|
||||
{
|
||||
sfx = s_sfx[i];
|
||||
Msg("%4i: ", i);
|
||||
|
||||
if( sfx->loaded )
|
||||
{
|
||||
samples += sfx->samples;
|
||||
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;
|
||||
}
|
||||
|
||||
if( sfx->name[0] == '#' ) Msg("%s", &sfx->name[1]);
|
||||
else Msg("sound/%s", sfx->name);
|
||||
|
||||
if( sfx->default_snd ) Msg(" (DEFAULTED)\n");
|
||||
else Msg("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if( sfx->name[0] == '*' ) Msg(" placeholder %s\n", sfx->name);
|
||||
else Msg(" not loaded %s\n", sfx->name);
|
||||
}
|
||||
}
|
||||
|
||||
Msg("-------------------------------------------\n");
|
||||
Msg("%i total samples\n", samples);
|
||||
Msg("%i total sounds\n", s_numSfx);
|
||||
Msg("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
info->samples = S_GetLittleLong() / info->width;
|
||||
|
||||
if( info->samples <= 0 )
|
||||
{
|
||||
MsgDev( D_WARN, "S_LoadWAV: file with 0 samples (%s)\n", 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, int width, int channels, sfx_t *sfx )
|
||||
{
|
||||
int size;
|
||||
|
||||
// calculate buffer size
|
||||
size = sfx->samples * width * channels;
|
||||
|
||||
// Set buffer format
|
||||
if( width == 2 )
|
||||
{
|
||||
if( channels == 2 ) sfx->format = AL_FORMAT_STEREO16;
|
||||
else sfx->format = AL_FORMAT_MONO16;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( channels == 2 ) sfx->format = AL_FORMAT_STEREO8;
|
||||
else sfx->format = AL_FORMAT_MONO8;
|
||||
}
|
||||
|
||||
// upload the sound
|
||||
palGenBuffers(1, &sfx->bufferNum);
|
||||
palBufferData(sfx->bufferNum, sfx->format, data, size, sfx->rate);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
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 );
|
||||
for( i = 0; i < info->samples; i++ )
|
||||
((short *)out)[i] = sin(i * 0.1f) * 20000;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_LoadSound
|
||||
=================
|
||||
*/
|
||||
bool S_LoadSound( sfx_t *sfx )
|
||||
{
|
||||
string name;
|
||||
byte *data;
|
||||
wavinfo_t info;
|
||||
|
||||
if( !sfx ) return false;
|
||||
if( sfx->name[0] == '*' ) return false;
|
||||
if( sfx->loaded ) return true; // see if still in memory
|
||||
|
||||
// load it from disk
|
||||
if( sfx->name[0] == '#' )
|
||||
com.snprintf( name, sizeof(name), "%s", &sfx->name[1]);
|
||||
else com.snprintf( name, sizeof(name), "sound/%s", sfx->name );
|
||||
|
||||
if(!S_LoadWAV(name, &data, &info))
|
||||
{
|
||||
sfx->default_snd = true;
|
||||
|
||||
MsgWarn( "couldn't find sound '%s', using default...\n", name );
|
||||
S_CreateDefaultSound( &data, &info );
|
||||
}
|
||||
|
||||
// load it in
|
||||
sfx->loaded = true;
|
||||
sfx->samples = info.samples;
|
||||
sfx->rate = info.rate;
|
||||
|
||||
S_UploadSound( data, info.width, info.channels, sfx );
|
||||
Mem_Free(data);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FindSound
|
||||
=================
|
||||
*/
|
||||
sfx_t *S_FindSound( const char *name )
|
||||
{
|
||||
sfx_t *sfx;
|
||||
uint hashKey;
|
||||
|
||||
if( !name || !name[0] )
|
||||
{
|
||||
MsgWarn("S_FindSound: empty name\n");
|
||||
return NULL;
|
||||
}
|
||||
if( com.strlen(name) >= MAX_STRING )
|
||||
{
|
||||
MsgWarn("S_FindSound: sound name too long: %s", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hashKey = Com_HashKey(name, SFX_HASHSIZE);
|
||||
for( sfx = s_sfxHash[hashKey]; sfx; sfx = sfx->nextHash )
|
||||
{
|
||||
if (!com.stricmp( sfx->name, name ))
|
||||
return sfx;
|
||||
}
|
||||
|
||||
// Create a new sfx_t
|
||||
if( s_numSfx == MAX_SFX )
|
||||
{
|
||||
MsgWarn("S_FindSound: MAX_SFX limit exceeded\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s_sfx[s_numSfx++] = sfx = Z_Malloc(sizeof(sfx_t));
|
||||
|
||||
// fill it in
|
||||
com.strncpy( sfx->name, name, sizeof(sfx->name));
|
||||
|
||||
// add to hash table
|
||||
sfx->nextHash = s_sfxHash[hashKey];
|
||||
s_sfxHash[hashKey] = sfx;
|
||||
|
||||
return sfx;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
S_BeginRegistration
|
||||
=====================
|
||||
*/
|
||||
void S_BeginRegistration( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
S_EndRegistration
|
||||
=====================
|
||||
*/
|
||||
void S_EndRegistration( void )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_RegisterSound
|
||||
=================
|
||||
*/
|
||||
sound_t S_RegisterSound( const char *name )
|
||||
{
|
||||
sfx_t *sfx;
|
||||
|
||||
if(!al_state.initialized)
|
||||
return 0;
|
||||
|
||||
sfx = S_FindSound( name );
|
||||
S_LoadSound( sfx );
|
||||
|
||||
if( !sfx ) return 0;
|
||||
return sfx - *s_sfx;
|
||||
}
|
||||
|
||||
sfx_t *S_GetSfxByHandle( sound_t handle )
|
||||
{
|
||||
if( handle < 0 || handle >= s_numSfx )
|
||||
{
|
||||
MsgWarn("S_GetSfxByHandle: handle %i out of range (%i)\n", handle, s_numSfx );
|
||||
return NULL;
|
||||
}
|
||||
return s_sfx[handle];
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FreeSounds
|
||||
=================
|
||||
*/
|
||||
void S_FreeSounds( void )
|
||||
{
|
||||
|
||||
sfx_t *sfx;
|
||||
int i;
|
||||
|
||||
// Stop all sounds
|
||||
S_StopAllSounds();
|
||||
|
||||
// Free all sounds
|
||||
for (i = 0; i < s_numSfx; i++){
|
||||
sfx = s_sfx[i];
|
||||
|
||||
palDeleteBuffers(1, &sfx->bufferNum);
|
||||
Mem_Free(sfx);
|
||||
}
|
||||
|
||||
memset( s_sfxHash, 0, sizeof(s_sfxHash));
|
||||
memset( s_sfx, 0, sizeof(s_sfx));
|
||||
|
||||
s_numSfx = 0;
|
||||
}
|
|
@ -0,0 +1,809 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// s_main.c - sound engine
|
||||
//=======================================================================
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
cvar_t *s_initSound;
|
||||
cvar_t *s_show;
|
||||
cvar_t *s_alDevice;
|
||||
cvar_t *s_allowExtensions;
|
||||
cvar_t *s_soundfx;
|
||||
cvar_t *s_ignoreALErrors;
|
||||
cvar_t *s_masterVolume;
|
||||
cvar_t *s_sfxVolume;
|
||||
cvar_t *s_musicVolume;
|
||||
cvar_t *s_minDistance;
|
||||
cvar_t *s_maxDistance;
|
||||
cvar_t *s_rolloffFactor;
|
||||
cvar_t *s_dopplerFactor;
|
||||
cvar_t *s_dopplerVelocity;
|
||||
|
||||
#define MAX_PLAYSOUNDS 128
|
||||
|
||||
#define MAX_CHANNELS 64
|
||||
|
||||
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 int s_numChannels;
|
||||
|
||||
static listener_t s_listener;
|
||||
|
||||
static int s_frameCount;
|
||||
|
||||
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}};
|
||||
|
||||
cvar_t *s_initSound;
|
||||
cvar_t *s_show;
|
||||
cvar_t *s_alDriver;
|
||||
cvar_t *s_alDevice;
|
||||
cvar_t *s_allowExtensions;
|
||||
cvar_t *s_ext_eax;
|
||||
cvar_t *s_ignoreALErrors;
|
||||
cvar_t *s_masterVolume;
|
||||
cvar_t *s_sfxVolume;
|
||||
cvar_t *s_musicVolume;
|
||||
cvar_t *s_minDistance;
|
||||
cvar_t *s_maxDistance;
|
||||
cvar_t *s_rolloffFactor;
|
||||
cvar_t *s_dopplerFactor;
|
||||
cvar_t *s_dopplerVelocity;
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
S_CheckForErrors
|
||||
=================
|
||||
*/
|
||||
static void S_CheckForErrors( void )
|
||||
{
|
||||
int err;
|
||||
char *str;
|
||||
|
||||
if((err = palGetError()) == AL_NO_ERROR)
|
||||
return;
|
||||
|
||||
switch( err )
|
||||
{
|
||||
case AL_INVALID_NAME:
|
||||
str = "AL_INVALID_NAME";
|
||||
break;
|
||||
case AL_INVALID_ENUM:
|
||||
str = "AL_INVALID_ENUM";
|
||||
break;
|
||||
case AL_INVALID_VALUE:
|
||||
str = "AL_INVALID_VALUE";
|
||||
break;
|
||||
case AL_INVALID_OPERATION:
|
||||
str = "AL_INVALID_OPERATION";
|
||||
break;
|
||||
case AL_OUT_OF_MEMORY:
|
||||
str = "AL_OUT_OF_MEMORY";
|
||||
break;
|
||||
default:
|
||||
str = "UNKNOWN ERROR";
|
||||
break;
|
||||
}
|
||||
Host_Error( "S_CheckForErrors: %s", str );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AllocChannels
|
||||
=================
|
||||
*/
|
||||
static void S_AllocChannels( void )
|
||||
{
|
||||
channel_t *ch;
|
||||
int i;
|
||||
|
||||
for( i = 0, ch = s_channels; i < MAX_CHANNELS; i++, ch++)
|
||||
{
|
||||
palGenSources(1, &ch->sourceNum);
|
||||
if(palGetError() != AL_NO_ERROR)
|
||||
break;
|
||||
al_state.num_channels++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FreeChannels
|
||||
=================
|
||||
*/
|
||||
static void S_FreeChannels( void )
|
||||
{
|
||||
channel_t *ch;
|
||||
int i;
|
||||
|
||||
for( i = 0, ch = s_channels; i < al_state.num_channels; i++, ch++ )
|
||||
{
|
||||
palDeleteSources(1, &ch->sourceNum);
|
||||
memset(ch, 0, sizeof(*ch));
|
||||
}
|
||||
al_state.num_channels = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_ChannelState
|
||||
=================
|
||||
*/
|
||||
static int S_ChannelState( channel_t *ch )
|
||||
{
|
||||
int state;
|
||||
|
||||
palGetSourcei( ch->sourceNum, AL_SOURCE_STATE, &state );
|
||||
return state;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_PlayChannel
|
||||
=================
|
||||
*/
|
||||
static void S_PlayChannel( channel_t *ch, sfx_t *sfx )
|
||||
{
|
||||
ch->sfx = sfx;
|
||||
|
||||
palSourcei(ch->sourceNum, AL_BUFFER, sfx->bufferNum);
|
||||
palSourcei(ch->sourceNum, AL_LOOPING, ch->loopsound);
|
||||
palSourcei(ch->sourceNum, AL_SOURCE_RELATIVE, false);
|
||||
palSourcePlay(ch->sourceNum);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StopChannel
|
||||
=================
|
||||
*/
|
||||
static void S_StopChannel( channel_t *ch )
|
||||
{
|
||||
ch->sfx = NULL;
|
||||
|
||||
palSourceStop(ch->sourceNum);
|
||||
palSourcei(ch->sourceNum, AL_BUFFER, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_SpatializeChannel
|
||||
=================
|
||||
*/
|
||||
static void S_SpatializeChannel( channel_t *ch )
|
||||
{
|
||||
vec3_t position, velocity;
|
||||
|
||||
// update position and velocity
|
||||
if( ch->entnum == al_state.clientnum || !ch->distanceMult )
|
||||
{
|
||||
palSourcefv(ch->sourceNum, AL_POSITION, s_listener.position);
|
||||
palSourcefv(ch->sourceNum, AL_VELOCITY, s_listener.velocity);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ch->fixedPosition )
|
||||
{
|
||||
palSource3f(ch->sourceNum, AL_POSITION, ch->position[1], ch->position[2], -ch->position[0]);
|
||||
palSource3f(ch->sourceNum, AL_VELOCITY, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( ch->loopsound ) si.GetSoundSpatialization(ch->loopnum, position, velocity);
|
||||
else si.GetSoundSpatialization( ch->entnum, position, velocity);
|
||||
|
||||
palSource3f(ch->sourceNum, AL_POSITION, position[1], position[2], -position[0]);
|
||||
palSource3f(ch->sourceNum, AL_VELOCITY, velocity[1], velocity[2], -velocity[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Update min/max distance
|
||||
if( ch->distanceMult )
|
||||
palSourcef(ch->sourceNum, AL_REFERENCE_DISTANCE, s_minDistance->value * ch->distanceMult );
|
||||
else palSourcef(ch->sourceNum, AL_REFERENCE_DISTANCE, s_maxDistance->value );
|
||||
|
||||
palSourcef( ch->sourceNum, AL_MAX_DISTANCE, s_maxDistance->value );
|
||||
|
||||
// update volume and rolloff factor
|
||||
palSourcef( ch->sourceNum, AL_GAIN, s_sfxVolume->value * ch->volume );
|
||||
palSourcef( ch->sourceNum, AL_ROLLOFF_FACTOR, s_rolloffFactor->value );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_PickChannel
|
||||
|
||||
Tries to find a free channel, or tries to replace an active channel
|
||||
=================
|
||||
*/
|
||||
channel_t *S_PickChannel( int entnum, int entChannel )
|
||||
{
|
||||
channel_t *ch;
|
||||
int i;
|
||||
int firstToDie = -1;
|
||||
int oldestTime = si.GetClientTime();
|
||||
|
||||
if( entnum < 0 || entChannel < 0 )
|
||||
Host_Error( "S_PickChannel: entnum or entChannel less than 0" );
|
||||
|
||||
for( i = 0, ch = s_channels; i < al_state.num_channels; i++, ch++ )
|
||||
{
|
||||
// don't let game sounds override streaming sounds
|
||||
if( ch->streaming )continue;
|
||||
|
||||
// check if this channel is active
|
||||
if( !ch->sfx )
|
||||
{
|
||||
// free channel
|
||||
firstToDie = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// channel 0 never overrides
|
||||
if( entChannel != 0 && (ch->entnum == entnum && ch->entchannel == entChannel))
|
||||
{
|
||||
// always override sound from same entity
|
||||
firstToDie = i;
|
||||
break;
|
||||
}
|
||||
|
||||
// don't let monster sounds override player sounds
|
||||
if( entnum != al_state.clientnum && ch->entnum == al_state.clientnum )
|
||||
continue;
|
||||
|
||||
// replace the oldest sound
|
||||
if( ch->startTime < oldestTime )
|
||||
{
|
||||
oldestTime = ch->startTime;
|
||||
firstToDie = i;
|
||||
}
|
||||
}
|
||||
|
||||
if( firstToDie == -1 ) return NULL;
|
||||
ch = &s_channels[firstToDie];
|
||||
|
||||
ch->entnum = entnum;
|
||||
ch->entchannel = entChannel;
|
||||
ch->startTime = si.GetClientTime();
|
||||
|
||||
// Make sure this channel is stopped
|
||||
palSourceStop(ch->sourceNum);
|
||||
palSourcei(ch->sourceNum, AL_BUFFER, 0);
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AddLoopingSounds
|
||||
|
||||
Entities with a sound field will generate looping sounds that are
|
||||
automatically started and stopped 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(!al_state.initialized )
|
||||
return false;
|
||||
sfx = S_GetSfxByHandle( handle );
|
||||
|
||||
// default looped sound it's terrible :)
|
||||
if( !sfx || !sfx->loaded || sfx->default_snd )
|
||||
return false;
|
||||
|
||||
// if this entity is already playing the same sound effect on an
|
||||
// active channel, then simply update it
|
||||
for( i = 0, ch = s_channels; i < al_state.num_channels; i++, ch++ )
|
||||
{
|
||||
if( ch->sfx != sfx ) continue;
|
||||
if( !ch->loopsound ) continue;
|
||||
if( ch->loopnum != entnum ) continue;
|
||||
if( ch->loopframe + 1 != al_state.framecount )
|
||||
continue;
|
||||
|
||||
ch->loopframe = al_state.framecount;
|
||||
break;
|
||||
}
|
||||
if( i != al_state.num_channels )
|
||||
return false;
|
||||
|
||||
// otherwise pick a channel and start the sound effect
|
||||
ch = S_PickChannel( 0, 0 );
|
||||
if( !ch )
|
||||
{
|
||||
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 false;
|
||||
}
|
||||
|
||||
ch->loopsound = true;
|
||||
ch->loopnum = entnum;
|
||||
ch->loopframe = al_state.framecount;
|
||||
ch->fixedPosition = false;
|
||||
ch->volume = 1.0;
|
||||
ch->distanceMult = 1.0 / ATTN_STATIC;
|
||||
|
||||
S_SpatializeChannel( ch );
|
||||
S_PlayChannel( ch, sfx );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AllocPlaySound
|
||||
=================
|
||||
*/
|
||||
static playSound_t *S_AllocPlaySound( void )
|
||||
{
|
||||
playSound_t *ps;
|
||||
|
||||
ps = s_freePlaySounds.next;
|
||||
if( ps == &s_freePlaySounds )
|
||||
return NULL; // No free playSounds
|
||||
|
||||
ps->prev->next = ps->next;
|
||||
ps->next->prev = ps->prev;
|
||||
|
||||
return ps;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_FreePlaySound
|
||||
=================
|
||||
*/
|
||||
static void S_FreePlaySound( playSound_t *ps )
|
||||
{
|
||||
ps->prev->next = ps->next;
|
||||
ps->next->prev = ps->prev;
|
||||
|
||||
// add to free list
|
||||
ps->next = s_freePlaySounds.next;
|
||||
s_freePlaySounds.next->prev = ps;
|
||||
ps->prev = &s_freePlaySounds;
|
||||
s_freePlaySounds.next = ps;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_IssuePlaySounds
|
||||
|
||||
Take all the pending playSounds and begin playing them.
|
||||
This is never called directly by S_Start*, but only by the update loop.
|
||||
=================
|
||||
*/
|
||||
static void S_IssuePlaySounds( void )
|
||||
{
|
||||
playSound_t *ps;
|
||||
channel_t *ch;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
ps = s_pendingPlaySounds.next;
|
||||
if(ps == &s_pendingPlaySounds)
|
||||
break; // no more pending playSounds
|
||||
|
||||
if( ps->beginTime > si.GetClientTime())
|
||||
break; // No more pending playSounds this frame
|
||||
|
||||
// pick a channel and start the sound effect
|
||||
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 );
|
||||
continue;
|
||||
}
|
||||
|
||||
ch->loopsound = false;
|
||||
ch->fixedPosition = ps->fixedPosition;
|
||||
VectorCopy( ps->position, ch->position );
|
||||
ch->volume = ps->volume;
|
||||
|
||||
if( ps->attenuation != ATTN_NONE ) ch->distanceMult = 1.0 / ps->attenuation;
|
||||
else ch->distanceMult = 0.0;
|
||||
|
||||
S_SpatializeChannel( ch );
|
||||
S_PlayChannel( ch, ps->sfx );
|
||||
|
||||
// free the playSound
|
||||
S_FreePlaySound( ps );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartSound
|
||||
|
||||
Validates the parms and queues the sound up.
|
||||
if origin is NULL, the sound will be dynamically sourced from the entity.
|
||||
entchannel 0 will never override a playing sound.
|
||||
=================
|
||||
*/
|
||||
void S_StartSound( const vec3_t position, int entnum, int entChannel, sound_t handle, float volume, float attenuation )
|
||||
{
|
||||
playSound_t *ps, *sort;
|
||||
sfx_t *sfx = NULL;
|
||||
|
||||
if(!al_state.initialized )
|
||||
return;
|
||||
|
||||
sfx = S_GetSfxByHandle( handle );
|
||||
if( !sfx ) return;
|
||||
|
||||
// Make sure the sound is loaded
|
||||
if(!S_LoadSound(sfx)) return;
|
||||
|
||||
// Allocate a playSound
|
||||
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;
|
||||
}
|
||||
|
||||
ps->sfx = sfx;
|
||||
ps->entnum = entnum;
|
||||
ps->entchannel = entChannel;
|
||||
|
||||
if( position )
|
||||
{
|
||||
ps->fixedPosition = true;
|
||||
VectorCopy( position, ps->position );
|
||||
}
|
||||
else ps->fixedPosition = false;
|
||||
|
||||
ps->volume = volume;
|
||||
ps->attenuation = attenuation;
|
||||
ps->beginTime = si.GetClientTime();
|
||||
|
||||
// Sort into the pending playSounds list
|
||||
for( sort = s_pendingPlaySounds.next; sort != &s_pendingPlaySounds&& sort->beginTime < ps->beginTime; sort = sort->next );
|
||||
|
||||
ps->next = sort;
|
||||
ps->prev = sort->prev;
|
||||
ps->next->prev = ps;
|
||||
ps->prev->next = ps;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartLocalSound
|
||||
|
||||
menu sound
|
||||
=================
|
||||
*/
|
||||
bool S_StartLocalSound( const char *name )
|
||||
{
|
||||
sound_t sfxHandle;
|
||||
|
||||
if(!al_state.initialized)
|
||||
return false;
|
||||
|
||||
sfxHandle = S_RegisterSound( name );
|
||||
S_StartSound( NULL, al_state.clientnum, 0, sfxHandle, 1.0f, ATTN_NONE );
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StopAllSounds
|
||||
=================
|
||||
*/
|
||||
void S_StopAllSounds( void )
|
||||
{
|
||||
channel_t *ch;
|
||||
int i;
|
||||
|
||||
if(!al_state.initialized)
|
||||
return;
|
||||
|
||||
// Clear all the playSounds
|
||||
memset( s_playSounds, 0, sizeof(s_playSounds));
|
||||
|
||||
s_freePlaySounds.next = s_freePlaySounds.prev = &s_freePlaySounds;
|
||||
s_pendingPlaySounds.next = s_pendingPlaySounds.prev = &s_pendingPlaySounds;
|
||||
|
||||
for( i = 0; i < MAX_PLAYSOUNDS; i++ )
|
||||
{
|
||||
s_playSounds[i].prev = &s_freePlaySounds;
|
||||
s_playSounds[i].next = s_freePlaySounds.next;
|
||||
s_playSounds[i].prev->next = &s_playSounds[i];
|
||||
s_playSounds[i].next->prev = &s_playSounds[i];
|
||||
}
|
||||
|
||||
// Stop all the channels
|
||||
for( i = 0, ch = s_channels; i < al_state.num_channels; i++, ch++ )
|
||||
{
|
||||
if( !ch->sfx ) continue;
|
||||
S_StopChannel( ch );
|
||||
}
|
||||
|
||||
S_StopStreaming(); // stop streaming channel
|
||||
S_StopBackgroundTrack(); // stop background track
|
||||
al_state.framecount = 0; // reset frame count
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_AddEnvironmentEffects
|
||||
|
||||
process all effects here
|
||||
=================
|
||||
*/
|
||||
void S_AddEnvironmentEffects( const vec3_t position )
|
||||
{
|
||||
uint eaxEnv;
|
||||
|
||||
if( !al_config.allow_3DMode ) return;
|
||||
|
||||
// if eax is enabled, apply listener environmental effects
|
||||
if( si.PointContents((float *)position ) & MASK_WATER )
|
||||
eaxEnv = EAX_ENVIRONMENT_UNDERWATER;
|
||||
else eaxEnv = EAX_ENVIRONMENT_GENERIC;
|
||||
al_config.Set3DMode(&DSPROPSETID_EAX20_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT|DSPROPERTY_EAXLISTENER_DEFERRED, 0, &eaxEnv, sizeof(eaxEnv));
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
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 )
|
||||
{
|
||||
channel_t *ch;
|
||||
int i;
|
||||
|
||||
if(!al_state.initialized ) return;
|
||||
|
||||
// Bump frame count
|
||||
al_state.framecount++;
|
||||
al_state.clientnum = clientnum;
|
||||
|
||||
// Set up listener
|
||||
VectorSet( s_listener.position, position[1], position[2], -position[0]);
|
||||
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];
|
||||
|
||||
palListenerfv(AL_POSITION, s_listener.position);
|
||||
palListenerfv(AL_VELOCITY, s_listener.velocity);
|
||||
palListenerfv(AL_ORIENTATION, s_listener.orientation);
|
||||
palListenerf(AL_GAIN, (al_state.active) ? s_masterVolume->value : 0.0f );
|
||||
|
||||
// Set state
|
||||
palDistanceModel( AL_INVERSE_DISTANCE_CLAMPED );
|
||||
|
||||
palDopplerFactor(s_dopplerFactor->value);
|
||||
palDopplerVelocity(s_dopplerVelocity->value);
|
||||
|
||||
S_AddEnvironmentEffects( position );
|
||||
|
||||
// Stream background track
|
||||
S_StreamBackgroundTrack();
|
||||
|
||||
// Add looping sounds
|
||||
si.AddLoopingSounds();
|
||||
|
||||
// Issue playSounds
|
||||
S_IssuePlaySounds();
|
||||
|
||||
// update spatialization for all sounds
|
||||
for( i = 0, ch = s_channels; i < al_state.num_channels; i++, ch++ )
|
||||
{
|
||||
if(!ch->sfx) continue; // not active
|
||||
|
||||
// check for stop
|
||||
if( ch->loopsound )
|
||||
{
|
||||
if(ch->loopframe != al_state.framecount)
|
||||
{
|
||||
S_StopChannel( ch );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( S_ChannelState( ch ) == AL_STOPPED )
|
||||
{
|
||||
S_StopChannel( ch );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// respatialize channel
|
||||
S_SpatializeChannel( ch );
|
||||
}
|
||||
|
||||
// check for errors
|
||||
if(!s_ignoreALErrors->integer)
|
||||
S_CheckForErrors();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_Activate
|
||||
|
||||
Called when the main window gains or loses focus.
|
||||
The window may have been destroyed and recreated between a deactivate
|
||||
and an activate.
|
||||
=================
|
||||
*/
|
||||
void S_Activate( bool active )
|
||||
{
|
||||
if(!al_state.initialized )
|
||||
return;
|
||||
|
||||
al_state.active = active;
|
||||
if( active ) palListenerf( AL_GAIN, s_masterVolume->value );
|
||||
else palListenerf( AL_GAIN, 0.0 );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_Play_f
|
||||
=================
|
||||
*/
|
||||
void S_Play_f( void )
|
||||
{
|
||||
int i = 1;
|
||||
string name;
|
||||
|
||||
if( Cmd_Argc() == 1 )
|
||||
{
|
||||
Msg("Usage: play <soundfile> [...]\n");
|
||||
return;
|
||||
}
|
||||
while ( i < Cmd_Argc())
|
||||
{
|
||||
if ( !com.strrchr(Cmd_Argv(i), '.')) com.sprintf( name, "%s.wav", Cmd_Argv(1) );
|
||||
else com.strncpy( name, Cmd_Argv(i), sizeof(name) );
|
||||
S_StartLocalSound( name );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_Music_f
|
||||
=================
|
||||
*/
|
||||
void S_Music_f( void )
|
||||
{
|
||||
int c = Cmd_Argc();
|
||||
|
||||
if( c == 2 ) S_StartBackgroundTrack( Cmd_Argv(1), Cmd_Argv(1) );
|
||||
else if( c == 3 ) S_StartBackgroundTrack( Cmd_Argv(1), Cmd_Argv(2) );
|
||||
else Msg("Usage: music <musicfile> [loopfile]\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StopSound_f
|
||||
=================
|
||||
*/
|
||||
void S_StopSound_f( void )
|
||||
{
|
||||
S_StopAllSounds();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_SoundInfo_f
|
||||
=================
|
||||
*/
|
||||
void S_SoundInfo_f( void )
|
||||
{
|
||||
if(!al_state.initialized )
|
||||
{
|
||||
Msg("Sound system not started\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Msg("\n");
|
||||
Msg("AL_VENDOR: %s\n", al_config.vendor_string);
|
||||
Msg("AL_RENDERER: %s\n", al_config.renderer_string);
|
||||
Msg("AL_VERSION: %s\n", al_config.version_string);
|
||||
Msg("AL_EXTENSIONS: %s\n", al_config.extensions_string);
|
||||
Msg("\n");
|
||||
Msg("DEVICE: %s\n", s_alDevice->string );
|
||||
Msg("CHANNELS: %i\n", al_state.num_channels);
|
||||
Msg("3D sound: %s\n", (al_config.allow_3DMode) ? "enabled" : "disabled" );
|
||||
Msg("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_Init
|
||||
=================
|
||||
*/
|
||||
void S_Init( void *hInst )
|
||||
{
|
||||
s_initSound = Cvar_Get("s_initsound", "1", CVAR_SYSTEMINFO );
|
||||
s_alDevice = Cvar_Get("s_device", "Generic Software", CVAR_LATCH|CVAR_ARCHIVE );
|
||||
s_allowExtensions = Cvar_Get("s_allowextensions", "1", CVAR_LATCH|CVAR_ARCHIVE );
|
||||
s_soundfx = Cvar_Get("s_soundfx", "1", CVAR_LATCH|CVAR_ARCHIVE );
|
||||
s_ignoreALErrors = Cvar_Get("s_ignoreALErrors", "1", CVAR_ARCHIVE );
|
||||
s_masterVolume = Cvar_Get("s_volume", "1.0", CVAR_ARCHIVE );
|
||||
s_sfxVolume = Cvar_Get("s_soundvolume", "1.0", CVAR_ARCHIVE );
|
||||
s_musicVolume = Cvar_Get("s_musicvolume", "1.0", CVAR_ARCHIVE );
|
||||
s_minDistance = Cvar_Get("s_mindistance", "240.0", CVAR_ARCHIVE );
|
||||
s_maxDistance = Cvar_Get("s_maxdistance", "8192.0", CVAR_ARCHIVE );
|
||||
s_rolloffFactor = Cvar_Get("s_rollofffactor", "1.0", CVAR_ARCHIVE );
|
||||
s_dopplerFactor = Cvar_Get("s_dopplerfactor", "1.0", CVAR_ARCHIVE );
|
||||
s_dopplerVelocity = Cvar_Get("s_dopplervelocity", "10976.0", CVAR_ARCHIVE );
|
||||
|
||||
Cmd_AddCommand("play", S_Play_f, "playing a specified sound file" );
|
||||
Cmd_AddCommand("music", S_Music_f, "starting a background track" );
|
||||
Cmd_AddCommand("s_stop", S_StopSound_f, "stop all sounds" );
|
||||
Cmd_AddCommand("s_info", S_SoundInfo_f, "print sound system information" );
|
||||
Cmd_AddCommand("soundlist", S_SoundList_f, "display loaded sounds" );
|
||||
|
||||
if(!s_initSound->integer)
|
||||
{
|
||||
MsgDev(D_INFO, "S_Init: sound system disabled\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
if(!S_Init_OpenAL())
|
||||
{
|
||||
MsgDev( D_INFO, "S_Init: sound system can't initialized\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sndpool = Mem_AllocPool("Sound Zone");
|
||||
al_state.initialized = true;
|
||||
|
||||
S_AllocChannels();
|
||||
S_StopAllSounds();
|
||||
|
||||
if(!s_ignoreALErrors->integer)
|
||||
S_CheckForErrors();
|
||||
|
||||
al_state.active = true; // enabled
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_Shutdown
|
||||
=================
|
||||
*/
|
||||
void S_Shutdown( void )
|
||||
{
|
||||
|
||||
Cmd_RemoveCommand( "play" );
|
||||
Cmd_RemoveCommand( "music" );
|
||||
Cmd_RemoveCommand( "s_stop" );
|
||||
Cmd_RemoveCommand( "s_info" );
|
||||
Cmd_RemoveCommand( "soundlist" );
|
||||
|
||||
if( !al_state.initialized )
|
||||
return;
|
||||
|
||||
S_FreeSounds();
|
||||
S_FreeChannels();
|
||||
|
||||
Mem_FreePool( &sndpool );
|
||||
S_Free_OpenAL();
|
||||
al_state.initialized = false;
|
||||
}
|
|
@ -0,0 +1,399 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// s_main.c - sound engine
|
||||
//=======================================================================
|
||||
|
||||
#include "sound.h"
|
||||
|
||||
static dllfunc_t openal_funcs[] =
|
||||
{
|
||||
{"alcOpenDevice", (void **) &palcOpenDevice },
|
||||
{"alcCloseDevice", (void **) &palcCloseDevice },
|
||||
{"alcCreateContext", (void **) &palcCreateContext },
|
||||
{"alcDestroyContext", (void **) &palcDestroyContext },
|
||||
{"alcMakeContextCurrent", (void **) &palcMakeContextCurrent },
|
||||
{"alcProcessContext", (void **) &palcProcessContext },
|
||||
{"alcSuspendContext", (void **) &palcSuspendContext },
|
||||
{"alcGetCurrentContext", (void **) &palcGetCurrentContext },
|
||||
{"alcGetContextsDevice", (void **) &palcGetContextsDevice },
|
||||
{"alcGetString", (void **) &palcGetString },
|
||||
{"alcGetIntegerv", (void **) &palcGetIntegerv },
|
||||
{"alcGetError", (void **) &palcGetError },
|
||||
{"alcIsExtensionPresent", (void **) &palcIsExtensionPresent },
|
||||
{"alcGetProcAddress", (void **) &palcGetProcAddress },
|
||||
{"alcGetEnumValue", (void **) &palcGetEnumValue },
|
||||
|
||||
{"alBufferData", (void **) &palBufferData },
|
||||
{"alDeleteBuffers", (void **) &palDeleteBuffers },
|
||||
{"alDeleteSources", (void **) &palDeleteSources },
|
||||
{"alDisable", (void **) &palDisable },
|
||||
{"alDistanceModel", (void **) &palDistanceModel },
|
||||
{"alDopplerFactor", (void **) &palDopplerFactor },
|
||||
{"alDopplerVelocity", (void **) &palDopplerVelocity },
|
||||
{"alEnable", (void **) &palEnable },
|
||||
{"alGenBuffers", (void **) &palGenBuffers },
|
||||
{"alGenSources", (void **) &palGenSources },
|
||||
{"alGetBoolean", (void **) &palGetBoolean },
|
||||
{"alGetBooleanv", (void **) &palGetBooleanv },
|
||||
{"alGetBufferf", (void **) &palGetBufferf },
|
||||
{"alGetBufferi", (void **) &palGetBufferi },
|
||||
{"alGetDouble", (void **) &palGetDouble },
|
||||
{"alGetDoublev", (void **) &palGetDoublev },
|
||||
{"alGetEnumValue", (void **) &palGetEnumValue },
|
||||
{"alGetError", (void **) &palGetError },
|
||||
{"alGetFloat", (void **) &palGetFloat },
|
||||
{"alGetFloatv", (void **) &palGetFloatv },
|
||||
{"alGetInteger", (void **) &palGetInteger },
|
||||
{"alGetIntegerv", (void **) &palGetIntegerv },
|
||||
{"alGetListener3f", (void **) &palGetListener3f },
|
||||
{"alGetListenerf", (void **) &palGetListenerf },
|
||||
{"alGetListenerfv", (void **) &palGetListenerfv },
|
||||
{"alGetListeneri", (void **) &palGetListeneri },
|
||||
{"alGetProcAddress", (void **) &palGetProcAddress },
|
||||
{"alGetSource3f", (void **) &palGetSource3f },
|
||||
{"alGetSourcef", (void **) &palGetSourcef },
|
||||
{"alGetSourcefv", (void **) &palGetSourcefv },
|
||||
{"alGetSourcei", (void **) &palGetSourcei },
|
||||
{"alGetString", (void **) &palGetString },
|
||||
{"alIsBuffer", (void **) &palIsBuffer },
|
||||
{"alIsEnabled", (void **) &palIsEnabled },
|
||||
{"alIsExtensionPresent", (void **) &palIsExtensionPresent },
|
||||
{"alIsSource", (void **) &palIsSource },
|
||||
{"alListener3f", (void **) &palListener3f },
|
||||
{"alListenerf", (void **) &palListenerf },
|
||||
{"alListenerfv", (void **) &palListenerfv },
|
||||
{"alListeneri", (void **) &palListeneri },
|
||||
{"alSource3f", (void **) &palSource3f },
|
||||
{"alSourcef", (void **) &palSourcef },
|
||||
{"alSourcefv", (void **) &palSourcefv },
|
||||
{"alSourcei", (void **) &palSourcei },
|
||||
{"alSourcePause", (void **) &palSourcePause },
|
||||
{"alSourcePausev", (void **) &palSourcePausev },
|
||||
{"alSourcePlay", (void **) &palSourcePlay },
|
||||
{"alSourcePlayv", (void **) &palSourcePlayv },
|
||||
{"alSourceQueueBuffers", (void **) &palSourceQueueBuffers },
|
||||
{"alSourceRewind", (void **) &palSourceRewind },
|
||||
{"alSourceRewindv", (void **) &palSourceRewindv },
|
||||
{"alSourceStop", (void **) &palSourceStop },
|
||||
{"alSourceStopv", (void **) &palSourceStopv },
|
||||
{"alSourceUnqueueBuffers", (void **) &palSourceUnqueueBuffers },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static dllfunc_t openal_effects[] =
|
||||
{
|
||||
{"alGenEffects", (void **) &alGenEffects },
|
||||
{"alDeleteEffects", (void **) &alDeleteEffects },
|
||||
{"alIsEffect", (void **) &alIsEffect },
|
||||
{"alEffecti", (void **) &alEffecti },
|
||||
{"alEffectiv", (void **) &alEffectiv },
|
||||
{"alEffectf", (void **) &alEffectf },
|
||||
{"alEffectfv", (void **) &alEffectfv },
|
||||
{"alGetEffecti", (void **) &alGetEffecti },
|
||||
{"alGetEffectiv", (void **) &alGetEffectiv },
|
||||
{"alGetEffectf", (void **) &alGetEffectf },
|
||||
{"alGetEffectfv", (void **) &alGetEffectfv },
|
||||
{"alGenFilters", (void **) &alGenFilters },
|
||||
{"alDeleteFilters", (void **) &alDeleteFilters },
|
||||
{"alIsFilter", (void **) &alIsFilter },
|
||||
{"alFilteri", (void **) &alFilteri },
|
||||
{"alFilteriv", (void **) &alFilteriv },
|
||||
{"alFilterf", (void **) &alFilterf },
|
||||
{"alFilterfv", (void **) &alFilterfv },
|
||||
{"alGetFilteri", (void **) &alGetFilteri },
|
||||
{"alGetFilteriv", (void **) &alGetFilteriv },
|
||||
{"alGetFilterf", (void **) &alGetFilterf },
|
||||
{"alGetFilterfv", (void **) &alGetFilterfv },
|
||||
{"alGenAuxiliaryEffectSlots", (void **) &alGenAuxiliaryEffectSlots },
|
||||
{"alDeleteAuxiliaryEffectSlots", (void **) &alDeleteAuxiliaryEffectSlots },
|
||||
{"alIsAuxiliaryEffectSlot", (void **) &alIsAuxiliaryEffectSlot },
|
||||
{"alAuxiliaryEffectSloti", (void **) &alAuxiliaryEffectSloti },
|
||||
{"alAuxiliaryEffectSlotiv", (void **) &alAuxiliaryEffectSlotiv },
|
||||
{"alAuxiliaryEffectSlotf", (void **) &alAuxiliaryEffectSlotf },
|
||||
{"alAuxiliaryEffectSlotfv", (void **) &alAuxiliaryEffectSlotfv },
|
||||
{"alGetAuxiliaryEffectSloti", (void **) &alGetAuxiliaryEffectSloti },
|
||||
{"alGetAuxiliaryEffectSlotiv", (void **) &alGetAuxiliaryEffectSlotiv },
|
||||
{"alGetAuxiliaryEffectSlotf", (void **) &alGetAuxiliaryEffectSlotf },
|
||||
{"alGetAuxiliaryEffectSlotfv", (void **) &alGetAuxiliaryEffectSlotfv },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
dll_info_t openal_dll = { "openal32.dll", openal_funcs, NULL, NULL, NULL, false, 0 };
|
||||
|
||||
alconfig_t al_config;
|
||||
alstate_t al_state;
|
||||
|
||||
cvar_t *s_eax;
|
||||
|
||||
/*
|
||||
=================
|
||||
S_InitDriver
|
||||
=================
|
||||
*/
|
||||
static bool S_InitDriver( void )
|
||||
{
|
||||
int attrlist[3] = { ALC_FREQUENCY, 44100, 0 };
|
||||
int *al_contxt = attrlist;
|
||||
|
||||
if((al_state.hDevice = palcOpenDevice( s_alDevice->string )) == NULL)
|
||||
{
|
||||
Msg("alOpenDevice - failed\n" );
|
||||
return false;
|
||||
}
|
||||
if((al_state.hALC = palcCreateContext( al_state.hDevice, al_contxt )) == NULL)
|
||||
goto failed;
|
||||
if(!palcMakeContextCurrent(al_state.hALC))
|
||||
goto failed;
|
||||
return true;
|
||||
|
||||
failed:
|
||||
if(al_state.hALC)
|
||||
{
|
||||
palcDestroyContext( al_state.hALC );
|
||||
al_state.hALC = NULL;
|
||||
}
|
||||
if(al_state.hDevice)
|
||||
{
|
||||
palcCloseDevice( al_state.hDevice );
|
||||
al_state.hDevice = NULL;
|
||||
}
|
||||
|
||||
// release openal at all
|
||||
Sys_FreeLibrary( &openal_dll );
|
||||
memset(&al_config, 0, sizeof(alconfig_t));
|
||||
memset(&al_state, 0, sizeof(alstate_t));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool S_SetupEFX( void )
|
||||
{
|
||||
const dllfunc_t *func;
|
||||
|
||||
// get the function pointers
|
||||
for(func = openal_effects; func && func->name != NULL; func++)
|
||||
{
|
||||
if (!(*func->func = palGetProcAddress( func->name )))
|
||||
{
|
||||
MsgDev(D_ERROR, "S_InitEffects: %s missing or invalid function\n", func->name );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void S_InitEffects( void )
|
||||
{
|
||||
uint uiEffects[1] = { 0 };
|
||||
|
||||
alGenEffects(1, &uiEffects[0]);
|
||||
if( palGetError() == AL_NO_ERROR )
|
||||
{
|
||||
MsgDev( D_NOTE, "S_InitEffects:" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_REVERB);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_revrb" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_EAXREVERB);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_eaxrevrb" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_CHORUS);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_chorus" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_DISTORTION);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_distortion" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_ECHO);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_echo" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_FLANGER);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_flanger" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_FREQUENCY_SHIFTER);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_frequency_shifter" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_VOCAL_MORPHER);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_vocal_morpher" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_PITCH_SHIFTER);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_pitch_shifter" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_RING_MODULATOR);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_ring_modulator" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_AUTOWAH);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_autowah" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_COMPRESSOR);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_compressor" );
|
||||
alEffecti(uiEffects[0], AL_EFFECT_TYPE, AL_EFFECT_EQUALIZER);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_equalizer" );
|
||||
MsgDev( D_NOTE, "\n" );
|
||||
}
|
||||
alDeleteEffects(1, &uiEffects[0]);
|
||||
}
|
||||
|
||||
static void S_InitFilters( void )
|
||||
{
|
||||
uint uiFilters[1] = { 0 };
|
||||
|
||||
alGenFilters(1, &uiFilters[0]);
|
||||
if( palGetError() == AL_NO_ERROR )
|
||||
{
|
||||
MsgDev( D_NOTE, "S_InitFilters:" );
|
||||
alFilteri(uiFilters[0], AL_FILTER_TYPE, AL_FILTER_LOWPASS);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_lowpass" );
|
||||
alFilteri(uiFilters[0], AL_FILTER_TYPE, AL_FILTER_HIGHPASS);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_highpass" );
|
||||
alFilteri(uiFilters[0], AL_FILTER_TYPE, AL_FILTER_BANDPASS);
|
||||
if(!palGetError()) MsgDev( D_NOTE, " ^3al_ext_bandpass" );
|
||||
MsgDev( D_NOTE, "\n" );
|
||||
}
|
||||
alDeleteFilters(1, &uiFilters[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_InitExtensions
|
||||
|
||||
grab extensions
|
||||
=================
|
||||
*/
|
||||
static void S_InitExtensions( void )
|
||||
{
|
||||
// set initial state
|
||||
al_config.Get3DMode = NULL;
|
||||
al_config.Set3DMode = NULL;
|
||||
al_config.allow_3DMode = false;
|
||||
|
||||
if( !s_soundfx->integer ) return;
|
||||
|
||||
// check I3DL2 extension for NVidia's Sound Storm chips. I3DL2 is hidden and can be missed in extension list.
|
||||
if( !com.strcmp( NVIDIA_DEVICE_NAME, al_config.deviceList[0] ))
|
||||
{
|
||||
I3DL2Get = (void *)palGetProcAddress("I3DL2Get");
|
||||
I3DL2Set = (void *)palGetProcAddress("I3DL2Set");
|
||||
if( I3DL2Get && I3DL2Set )
|
||||
{
|
||||
al_config.allow_3DMode = true;
|
||||
al_config.Get3DMode = I3DL2Get;
|
||||
al_config.Set3DMode = I3DL2Set;
|
||||
MsgDev( D_NOTE, "S_InitExtensions: enable I3DL2\n" );
|
||||
}
|
||||
}
|
||||
if( palIsExtensionPresent("EAX3.0") && !al_config.allow_3DMode )
|
||||
{
|
||||
alEAXSet = (void *)palGetProcAddress( "EAXSet" );
|
||||
alEAXGet = (void *)palGetProcAddress( "EAXGet" );
|
||||
if( alEAXSet && alEAXGet )
|
||||
{
|
||||
al_config.allow_3DMode = true;
|
||||
al_config.Get3DMode = alEAXGet;
|
||||
al_config.Set3DMode = alEAXSet;
|
||||
MsgDev( D_NOTE, "S_InitExtensions: enable EAX 3.0\n" );
|
||||
}
|
||||
}
|
||||
if( palIsExtensionPresent("EAX2.0") && !al_config.allow_3DMode )
|
||||
{
|
||||
alEAXSet = (void *)palGetProcAddress( "EAXSet" );
|
||||
alEAXGet = (void *)palGetProcAddress( "EAXGet" );
|
||||
if( alEAXSet && alEAXGet )
|
||||
{
|
||||
al_config.allow_3DMode = true;
|
||||
al_config.Get3DMode = alEAXGet;
|
||||
al_config.Set3DMode = alEAXSet;
|
||||
MsgDev( D_NOTE, "S_InitExtensions: enable EAX 2.0\n" );
|
||||
}
|
||||
}
|
||||
if( palIsExtensionPresent("EAX") && !al_config.allow_3DMode )
|
||||
{
|
||||
alEAXSet = (void *)palGetProcAddress( "EAXSet" );
|
||||
alEAXGet = (void *)palGetProcAddress( "EAXGet" );
|
||||
if( alEAXSet && alEAXGet )
|
||||
{
|
||||
al_config.allow_3DMode = true;
|
||||
al_config.Get3DMode = alEAXGet;
|
||||
al_config.Set3DMode = alEAXSet;
|
||||
MsgDev( D_NOTE, "S_InitExtensions: enable EAX 1.0\n" );
|
||||
}
|
||||
}
|
||||
|
||||
if(palcIsExtensionPresent( al_state.hDevice, "ALC_EXT_EFX"))
|
||||
{
|
||||
|
||||
uint uiEffectSlots[MAX_EFFECTS] = { 0 };
|
||||
|
||||
if(!S_SetupEFX()) return;
|
||||
|
||||
// testing effect slots
|
||||
for( al_config.num_slots = 0; al_config.num_slots < MAX_EFFECTS; al_config.num_slots++ )
|
||||
{
|
||||
alGenAuxiliaryEffectSlots( 1, &uiEffectSlots[al_config.num_slots] );
|
||||
if( palGetError() != AL_NO_ERROR) break;
|
||||
|
||||
}
|
||||
palcGetIntegerv( al_state.hDevice, ALC_MAX_AUXILIARY_SENDS, 1, &al_config.num_sends );
|
||||
|
||||
S_InitEffects();
|
||||
S_InitFilters();
|
||||
|
||||
alDeleteAuxiliaryEffectSlots( al_config.num_slots, uiEffectSlots );
|
||||
}
|
||||
}
|
||||
|
||||
bool S_Init_OpenAL( void )
|
||||
{
|
||||
Sys_LoadLibrary( &openal_dll );
|
||||
|
||||
if( !openal_dll.link )
|
||||
{
|
||||
MsgDev( D_ERROR, "OpenAL driver not installed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get device list
|
||||
if( palcIsExtensionPresent( NULL, "ALC_ENUMERATION_EXT"))
|
||||
{
|
||||
// get list of devices
|
||||
const char *device_enum = palcGetString( NULL, ALC_DEVICE_SPECIFIER );
|
||||
al_config.defDevice = palcGetString( NULL, ALC_DEFAULT_DEVICE_SPECIFIER );
|
||||
|
||||
while( *device_enum )
|
||||
{
|
||||
// enumerate devices
|
||||
com.strncpy( al_config.deviceList[al_config.device_count++], device_enum, MAX_STRING );
|
||||
while(*device_enum) device_enum++;
|
||||
device_enum++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgDev( D_ERROR, "can't enumerate OpenAL devices\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize the device, context, etc...
|
||||
if(!S_InitDriver()) return false;
|
||||
|
||||
// get some openal strings
|
||||
al_config.vendor_string = palGetString(AL_VENDOR);
|
||||
al_config.renderer_string = palGetString(AL_RENDERER); // stupid name :)
|
||||
al_config.version_string = palGetString(AL_VERSION);
|
||||
al_config.extensions_string = palGetString(AL_EXTENSIONS);
|
||||
MsgDev(D_INFO, "Audio: %s\n", al_config.renderer_string );
|
||||
|
||||
// Initialize extensions
|
||||
S_InitExtensions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void S_Free_OpenAL( void )
|
||||
{
|
||||
if( al_state.hALC )
|
||||
{
|
||||
if( palcMakeContextCurrent )
|
||||
palcMakeContextCurrent( NULL );
|
||||
if( palcDestroyContext )
|
||||
palcDestroyContext( al_state.hALC );
|
||||
al_state.hALC = NULL;
|
||||
}
|
||||
if( al_state.hDevice )
|
||||
{
|
||||
if( palcCloseDevice )
|
||||
palcCloseDevice( al_state.hDevice );
|
||||
al_state.hDevice = NULL;
|
||||
}
|
||||
|
||||
Sys_FreeLibrary( &openal_dll );
|
||||
memset(&al_config, 0, sizeof(alconfig_t));
|
||||
memset(&al_state, 0, sizeof(alstate_t));
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// s_openal.h - openal definition
|
||||
//=======================================================================
|
||||
|
||||
#ifndef S_OPENAL_H
|
||||
#define S_OPENAL_H
|
||||
|
||||
typedef struct aldevice_s aldevice;
|
||||
typedef struct alcontext_s alcontext;
|
||||
|
||||
#define NVIDIA_DEVICE_NAME "NVIDIA(R) nForce(TM) Audio"
|
||||
#define MAX_EFFECTS 128
|
||||
|
||||
#define AL_VENDOR 0xB001
|
||||
#define AL_VERSION 0xB002
|
||||
#define AL_RENDERER 0xB003
|
||||
#define AL_EXTENSIONS 0xB004
|
||||
#define ALC_DEFAULT_DEVICE_SPECIFIER 0x1004
|
||||
#define ALC_DEVICE_SPECIFIER 0x1005
|
||||
#define ALC_EXTENSIONS 0x1006
|
||||
#define ALC_MAJOR_VERSION 0x1000
|
||||
#define ALC_MINOR_VERSION 0x1001
|
||||
#define ALC_ATTRIBUTES_SIZE 0x1002
|
||||
#define ALC_ALL_ATTRIBUTES 0x1003
|
||||
#define ALC_FREQUENCY 0x1007
|
||||
#define ALC_MAX_AUXILIARY_SENDS 0x20003
|
||||
|
||||
#define AL_SOURCE_RELATIVE 0x202
|
||||
#define AL_CONE_INNER_ANGLE 0x1001
|
||||
#define AL_CONE_OUTER_ANGLE 0x1002
|
||||
#define AL_PITCH 0x1003
|
||||
#define AL_POSITION 0x1004
|
||||
#define AL_DIRECTION 0x1005
|
||||
#define AL_VELOCITY 0x1006
|
||||
#define AL_LOOPING 0x1007
|
||||
#define AL_BUFFER 0x1009
|
||||
#define AL_GAIN 0x100A
|
||||
#define AL_MIN_GAIN 0x100D
|
||||
#define AL_MAX_GAIN 0x100E
|
||||
#define AL_ORIENTATION 0x100F
|
||||
|
||||
#define AL_SOURCE_STATE 0x1010
|
||||
#define AL_INITIAL 0x1011
|
||||
#define AL_PLAYING 0x1012
|
||||
#define AL_PAUSED 0x1013
|
||||
#define AL_STOPPED 0x1014
|
||||
|
||||
#define AL_REFERENCE_DISTANCE 0x1020
|
||||
#define AL_ROLLOFF_FACTOR 0x1021
|
||||
#define AL_CONE_OUTER_GAIN 0x1022
|
||||
#define AL_MAX_DISTANCE 0x1023
|
||||
|
||||
#define AL_DISTANCE_MODEL 0xD000
|
||||
#define AL_INVERSE_DISTANCE 0xD001
|
||||
#define AL_INVERSE_DISTANCE_CLAMPED 0xD002
|
||||
#define AL_LINEAR_DISTANCE 0xD003
|
||||
#define AL_LINEAR_DISTANCE_CLAMPED 0xD004
|
||||
#define AL_EXPONENT_DISTANCE 0xD005
|
||||
#define AL_EXPONENT_DISTANCE_CLAMPED 0xD006
|
||||
|
||||
// sound format
|
||||
#define AL_FORMAT_MONO8 0x1100
|
||||
#define AL_FORMAT_MONO16 0x1101
|
||||
#define AL_FORMAT_STEREO8 0x1102
|
||||
#define AL_FORMAT_STEREO16 0x1103
|
||||
|
||||
// buffer queues
|
||||
#define AL_BUFFERS_QUEUED 0x1015
|
||||
#define AL_BUFFERS_PROCESSED 0x1016
|
||||
|
||||
// openal errors
|
||||
#define AL_NO_ERROR 0
|
||||
#define AL_INVALID_NAME 0xA001
|
||||
#define AL_INVALID_ENUM 0xA002
|
||||
#define AL_INVALID_VALUE 0xA003
|
||||
#define AL_INVALID_OPERATION 0xA004
|
||||
#define AL_OUT_OF_MEMORY 0xA005
|
||||
|
||||
// openal effects
|
||||
#define AL_EFFECT_TYPE 0x8001
|
||||
#define AL_EFFECT_NULL 0x0000
|
||||
#define AL_EFFECT_REVERB 0x0001
|
||||
#define AL_EFFECT_CHORUS 0x0002
|
||||
#define AL_EFFECT_DISTORTION 0x0003
|
||||
#define AL_EFFECT_ECHO 0x0004
|
||||
#define AL_EFFECT_FLANGER 0x0005
|
||||
#define AL_EFFECT_FREQUENCY_SHIFTER 0x0006
|
||||
#define AL_EFFECT_VOCAL_MORPHER 0x0007
|
||||
#define AL_EFFECT_PITCH_SHIFTER 0x0008
|
||||
#define AL_EFFECT_RING_MODULATOR 0x0009
|
||||
#define AL_EFFECT_AUTOWAH 0x000A
|
||||
#define AL_EFFECT_COMPRESSOR 0x000B
|
||||
#define AL_EFFECT_EQUALIZER 0x000C
|
||||
#define AL_EFFECT_EAXREVERB 0x8000
|
||||
|
||||
// openal filters
|
||||
#define AL_FILTER_TYPE 0x8001
|
||||
#define AL_FILTER_NULL 0x0000
|
||||
#define AL_FILTER_LOWPASS 0x0001
|
||||
#define AL_FILTER_HIGHPASS 0x0002
|
||||
#define AL_FILTER_BANDPASS 0x0003
|
||||
|
||||
enum
|
||||
{
|
||||
EAX_ENVIRONMENT_GENERIC,
|
||||
EAX_ENVIRONMENT_PADDEDCELL,
|
||||
EAX_ENVIRONMENT_ROOM,
|
||||
EAX_ENVIRONMENT_BATHROOM,
|
||||
EAX_ENVIRONMENT_LIVINGROOM,
|
||||
EAX_ENVIRONMENT_STONEROOM,
|
||||
EAX_ENVIRONMENT_AUDITORIUM,
|
||||
EAX_ENVIRONMENT_CONCERTHALL,
|
||||
EAX_ENVIRONMENT_CAVE,
|
||||
EAX_ENVIRONMENT_ARENA,
|
||||
EAX_ENVIRONMENT_HANGAR,
|
||||
EAX_ENVIRONMENT_CARPETEDHALLWAY,
|
||||
EAX_ENVIRONMENT_HALLWAY,
|
||||
EAX_ENVIRONMENT_STONECORRIDOR,
|
||||
EAX_ENVIRONMENT_ALLEY,
|
||||
EAX_ENVIRONMENT_FOREST,
|
||||
EAX_ENVIRONMENT_CITY,
|
||||
EAX_ENVIRONMENT_MOUNTAINS,
|
||||
EAX_ENVIRONMENT_QUARRY,
|
||||
EAX_ENVIRONMENT_PLAIN,
|
||||
EAX_ENVIRONMENT_PARKINGLOT,
|
||||
EAX_ENVIRONMENT_SEWERPIPE,
|
||||
EAX_ENVIRONMENT_UNDERWATER,
|
||||
EAX_ENVIRONMENT_DRUGGED,
|
||||
EAX_ENVIRONMENT_DIZZY,
|
||||
EAX_ENVIRONMENT_PSYCHOTIC,
|
||||
|
||||
EAX_ENVIRONMENT_COUNT
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DSPROPERTY_EAXLISTENER_NONE,
|
||||
DSPROPERTY_EAXLISTENER_ALLPARAMETERS,
|
||||
DSPROPERTY_EAXLISTENER_ROOM,
|
||||
DSPROPERTY_EAXLISTENER_ROOMHF,
|
||||
DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR,
|
||||
DSPROPERTY_EAXLISTENER_DECAYTIME,
|
||||
DSPROPERTY_EAXLISTENER_DECAYHFRATIO,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONS,
|
||||
DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY,
|
||||
DSPROPERTY_EAXLISTENER_REVERB,
|
||||
DSPROPERTY_EAXLISTENER_REVERBDELAY,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENT,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE,
|
||||
DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION,
|
||||
DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF,
|
||||
|
||||
DSPROPERTY_EAXLISTENER_FLAGS
|
||||
} DSPROPERTY_EAX_LISTENERPROPERTY;
|
||||
|
||||
// or these flags with property id
|
||||
#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
|
||||
#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later
|
||||
|
||||
// openal32.dll exports
|
||||
aldevice *(_cdecl *palcOpenDevice)( const char *devicename );
|
||||
char (_cdecl *palcCloseDevice)( aldevice *device );
|
||||
alcontext *(_cdecl *palcCreateContext)( aldevice *device, const int *attrlist );
|
||||
void (_cdecl *palcDestroyContext)( alcontext *context );
|
||||
char (_cdecl *palcMakeContextCurrent)( alcontext *context );
|
||||
void (_cdecl *palcProcessContext)( alcontext *context );
|
||||
void (_cdecl *palcSuspendContext)( alcontext *context );
|
||||
alcontext *(_cdecl *palcGetCurrentContext)( void );
|
||||
aldevice *(_cdecl *palcGetContextsDevice)( alcontext *context );
|
||||
const char *(_cdecl *palcGetString )( aldevice *device, int param );
|
||||
void (_cdecl *palcGetIntegerv)( aldevice *device, int param, int size, int *dest );
|
||||
int (_cdecl *palcGetError)( aldevice *device );
|
||||
char (_cdecl *palcIsExtensionPresent)( aldevice *device, const char *extname );
|
||||
void *(_cdecl *palcGetProcAddress)( aldevice *device, const char *funcname );
|
||||
int (_cdecl *palcGetEnumValue)( aldevice *device, const char *enumname );
|
||||
|
||||
void (_cdecl *palBufferData)( uint bid, int format, const void* data, int size, int freq );
|
||||
void (_cdecl *palDeleteBuffers)( int n, const uint* buffers );
|
||||
void (_cdecl *palDeleteSources)( int n, const uint* sources );
|
||||
void (_cdecl *palDisable)( int capability );
|
||||
void (_cdecl *palDistanceModel)( int distanceModel );
|
||||
void (_cdecl *palDopplerFactor)( float value );
|
||||
void (_cdecl *palDopplerVelocity)( float value );
|
||||
void (_cdecl *palEnable)( int capability );
|
||||
void (_cdecl *palGenBuffers)( int n, uint* buffers );
|
||||
void (_cdecl *palGenSources)( int n, uint* sources );
|
||||
char (_cdecl *palGetBoolean)( int param );
|
||||
void (_cdecl *palGetBooleanv)( int param, char* data );
|
||||
void (_cdecl *palGetBufferf)( uint bid, int param, float* value );
|
||||
void (_cdecl *palGetBufferi)( uint bid, int param, int* value );
|
||||
double (_cdecl *palGetDouble)( int param );
|
||||
void (_cdecl *palGetDoublev)( int param, double* data );
|
||||
int (_cdecl *palGetEnumValue)( const char* ename );
|
||||
int (_cdecl *palGetError)( void );
|
||||
float (_cdecl *palGetFloat)( int param );
|
||||
void (_cdecl *palGetFloatv)( int param, float* data );
|
||||
int (_cdecl *palGetInteger)( int param );
|
||||
void (_cdecl *palGetIntegerv)( int param, int* data );
|
||||
void (_cdecl *palGetListener3f)( int param, float *value1, float *value2, float *value3 );
|
||||
void (_cdecl *palGetListenerf)( int param, float* value );
|
||||
void (_cdecl *palGetListenerfv)( int param, float* values );
|
||||
void (_cdecl *palGetListeneri)( int param, int* value );
|
||||
void *(_cdecl *palGetProcAddress)( const char* fname );
|
||||
void (_cdecl *palGetSource3f)( uint sid, int param, float* value1, float* value2, float* value3 );
|
||||
void (_cdecl *palGetSourcef)( uint sid, int param, float* value );
|
||||
void (_cdecl *palGetSourcefv)( uint sid, int param, float* values );
|
||||
void (_cdecl *palGetSourcei)( uint sid, int param, int* value );
|
||||
const char *(_cdecl *palGetString)( int param );
|
||||
char (_cdecl *palIsBuffer)( uint bid );
|
||||
char (_cdecl *palIsEnabled)( int capability );
|
||||
char (_cdecl *palIsExtensionPresent)(const char* extname );
|
||||
char (_cdecl *palIsSource)( uint sid );
|
||||
void (_cdecl *palListener3f)( int param, float value1, float value2, float value3 );
|
||||
void (_cdecl *palListenerf)( int param, float value );
|
||||
void (_cdecl *palListenerfv)( int param, const float* values );
|
||||
void (_cdecl *palListeneri)( int param, int value );
|
||||
void (_cdecl *palSource3f)( uint sid, int param, float value1, float value2, float value3 );
|
||||
void (_cdecl *palSourcef)( uint sid, int param, float value );
|
||||
void (_cdecl *palSourcefv)( uint sid, int param, const float* values );
|
||||
void (_cdecl *palSourcei)( uint sid, int param, int value);
|
||||
void (_cdecl *palSourcePause)( uint sid );
|
||||
void (_cdecl *palSourcePausev)( int ns, const uint *sids );
|
||||
void (_cdecl *palSourcePlay)( uint sid );
|
||||
void (_cdecl *palSourcePlayv)( int ns, const uint *sids );
|
||||
void (_cdecl *palSourceQueueBuffers)(uint sid, int numEntries, const uint *bids );
|
||||
void (_cdecl *palSourceRewind)( uint sid );
|
||||
void (_cdecl *palSourceRewindv)( int ns, const uint *sids );
|
||||
void (_cdecl *palSourceStop)( uint sid );
|
||||
void (_cdecl *palSourceStopv)( int ns, const uint *sids );
|
||||
void (_cdecl *palSourceUnqueueBuffers)(uint sid, int numEntries, uint *bids );
|
||||
|
||||
// openal32.dll internal exports which can be get with by algetProcAddress
|
||||
void (*alGenEffects)( int n, uint* effects );
|
||||
void (*alDeleteEffects)( int n, uint* effects );
|
||||
char (*alIsEffect)( uint eid );
|
||||
void (*alEffecti)( uint eid, int param, int value);
|
||||
void (*alEffectiv)( uint eid, int param, int* values );
|
||||
void (*alEffectf)( uint eid, int param, float value);
|
||||
void (*alEffectfv)( uint eid, int param, float* values );
|
||||
void (*alGetEffecti)( uint eid, int pname, int* value );
|
||||
void (*alGetEffectiv)( uint eid, int pname, int* values );
|
||||
void (*alGetEffectf)( uint eid, int pname, float* value );
|
||||
void (*alGetEffectfv)( uint eid, int pname, float* values );
|
||||
void (*alGenFilters)( int n, uint* filters );
|
||||
void (*alDeleteFilters)( int n, uint* filters );
|
||||
char (*alIsFilter)( uint fid );
|
||||
void (*alFilteri)( uint fid, int param, int value );
|
||||
void (*alFilteriv)( uint fid, int param, int* values );
|
||||
void (*alFilterf)( uint fid, int param, float value);
|
||||
void (*alFilterfv)( uint fid, int param, float* values );
|
||||
void (*alGetFilteri)( uint fid, int pname, int* value );
|
||||
void (*alGetFilteriv)( uint fid, int pname, int* values );
|
||||
void (*alGetFilterf)( uint fid, int pname, float* value );
|
||||
void (*alGetFilterfv)( uint fid, int pname, float* values );
|
||||
void (*alGenAuxiliaryEffectSlots)( int n, uint* slots );
|
||||
void (*alDeleteAuxiliaryEffectSlots)( int n, uint* slots );
|
||||
char (*alIsAuxiliaryEffectSlot)( uint slot );
|
||||
void (*alAuxiliaryEffectSloti)( uint asid, int param, int value );
|
||||
void (*alAuxiliaryEffectSlotiv)( uint asid, int param, int* values );
|
||||
void (*alAuxiliaryEffectSlotf)( uint asid, int param, float value );
|
||||
void (*alAuxiliaryEffectSlotfv)( uint asid, int param, float* values );
|
||||
void (*alGetAuxiliaryEffectSloti)( uint asid, int pname, int* value );
|
||||
void (*alGetAuxiliaryEffectSlotiv)( uint asid, int pname, int* values );
|
||||
void (*alGetAuxiliaryEffectSlotf)( uint asid, int pname, float* value );
|
||||
void (*alGetAuxiliaryEffectSlotfv)( uint asid, int pname, float* values );
|
||||
|
||||
typedef struct guid_s
|
||||
{
|
||||
dword Data1;
|
||||
word Data2;
|
||||
word Data3;
|
||||
byte Data4[8];
|
||||
} guid_t;
|
||||
|
||||
// EAX 2.0 extension
|
||||
int (*alEAXSet)( const guid_t*, uint, uint, void*, uint );
|
||||
int (*alEAXGet)( const guid_t*, uint, uint, void*, uint );
|
||||
|
||||
// I3DL2 OpenAL Extension
|
||||
int (*I3DL2Get)( const guid_t*, uint, uint, void*, uint );
|
||||
int (*I3DL2Set)( const guid_t*, uint, uint, void*, uint );
|
||||
|
||||
bool S_Init_OpenAL( void );
|
||||
void S_Free_OpenAL( void );
|
||||
|
||||
#endif//S_OPENAL_H
|
|
@ -0,0 +1,367 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// s_stream.c - sound streaming
|
||||
//=======================================================================
|
||||
|
||||
#include "sound.h"
|
||||
#include "s_stream.h"
|
||||
|
||||
#define BUFFER_SIZE 16384
|
||||
|
||||
static bg_track_t s_bgTrack;
|
||||
static channel_t *s_streamingChannel;
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
||||
OGG VORBIS STREAMING
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
static size_t ovc_read( void *ptr, size_t size, size_t nmemb, void *datasource )
|
||||
{
|
||||
bg_track_t *track = (bg_track_t *)datasource;
|
||||
|
||||
if (!size || !nmemb)
|
||||
return 0;
|
||||
|
||||
return FS_Read( track->file, ptr, size * nmemb ) / size;
|
||||
}
|
||||
|
||||
static int ovc_seek ( void *datasource, ogg_int64_t offset, int whence )
|
||||
{
|
||||
bg_track_t *track = (bg_track_t *)datasource;
|
||||
|
||||
switch( whence )
|
||||
{
|
||||
case SEEK_SET:
|
||||
FS_Seek(track->file, (int)offset, SEEK_SET);
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
FS_Seek(track->file, (int)offset, SEEK_CUR);
|
||||
break;
|
||||
case SEEK_END:
|
||||
FS_Seek(track->file, (int)offset, SEEK_END);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ovc_close( void *datasource )
|
||||
{
|
||||
bg_track_t *track = (bg_track_t *)datasource;
|
||||
|
||||
//FIXME: FS_Close( track->file );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long ovc_tell (void *datasource)
|
||||
{
|
||||
bg_track_t *track = (bg_track_t *)datasource;
|
||||
|
||||
return FS_Tell( track->file );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_OpenBackgroundTrack
|
||||
=================
|
||||
*/
|
||||
static bool S_OpenBackgroundTrack (const char *name, bg_track_t *track)
|
||||
{
|
||||
vorbisfile_t *vorbisFile;
|
||||
vorbis_info_t *vorbisInfo;
|
||||
ov_callbacks_t vorbisCallbacks = { ovc_read, ovc_seek, ovc_close, ovc_tell };
|
||||
|
||||
track->file = FS_Open( name, "rb" );
|
||||
if( !track->file )
|
||||
{
|
||||
MsgWarn( "S_OpenBackgroundTrack: couldn't find %s\n", name );
|
||||
return false;
|
||||
}
|
||||
track->vorbisFile = vorbisFile = Z_Malloc(sizeof(vorbisfile_t));
|
||||
|
||||
if( ov_open_callbacks(track, vorbisFile, NULL, 0, vorbisCallbacks) < 0 )
|
||||
{
|
||||
MsgWarn( "S_OpenBackgroundTrack: couldn't open ogg stream %s\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
vorbisInfo = ov_info( vorbisFile, -1 );
|
||||
if( vorbisInfo->channels != 1 && vorbisInfo->channels != 2)
|
||||
{
|
||||
MsgWarn( "S_OpenBackgroundTrack: only mono and stereo ogg files supported %s\n", name );
|
||||
return false;
|
||||
}
|
||||
|
||||
track->start = ov_raw_tell( vorbisFile );
|
||||
track->rate = vorbisInfo->rate;
|
||||
track->format = (vorbisInfo->channels == 2) ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_CloseBackgroundTrack
|
||||
=================
|
||||
*/
|
||||
static void S_CloseBackgroundTrack( bg_track_t *track )
|
||||
{
|
||||
if( track->vorbisFile )
|
||||
{
|
||||
ov_clear( track->vorbisFile );
|
||||
Mem_Free( track->vorbisFile );
|
||||
track->vorbisFile = NULL;
|
||||
}
|
||||
if( track->file )
|
||||
{
|
||||
FS_Close( track->file );
|
||||
track->file = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StreamBackgroundTrack
|
||||
=================
|
||||
*/
|
||||
void S_StreamBackgroundTrack( void )
|
||||
{
|
||||
byte data[BUFFER_SIZE];
|
||||
int processed, queued, state;
|
||||
int size, read, dummy;
|
||||
uint buffer;
|
||||
|
||||
if( !s_bgTrack.file || !s_musicVolume->value )
|
||||
return;
|
||||
if(!s_streamingChannel) return;
|
||||
|
||||
// unqueue and delete any processed buffers
|
||||
palGetSourcei( s_streamingChannel->sourceNum, AL_BUFFERS_PROCESSED, &processed );
|
||||
if( processed > 0 )
|
||||
{
|
||||
while( processed-- )
|
||||
{
|
||||
palSourceUnqueueBuffers(s_streamingChannel->sourceNum, 1, &buffer);
|
||||
palDeleteBuffers(1, &buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// make sure we always have at least 4 buffers in the queue
|
||||
palGetSourcei( s_streamingChannel->sourceNum, AL_BUFFERS_QUEUED, &queued );
|
||||
while( queued < 4 )
|
||||
{
|
||||
size = 0;
|
||||
// stream from disk
|
||||
while( size < BUFFER_SIZE )
|
||||
{
|
||||
read = ov_read( s_bgTrack.vorbisFile, data + size, BUFFER_SIZE - size, 0, 2, 1, &dummy );
|
||||
if( read == 0 )
|
||||
{
|
||||
// end of file
|
||||
if(!s_bgTrack.looping)
|
||||
{
|
||||
// close the intro track
|
||||
S_CloseBackgroundTrack( &s_bgTrack );
|
||||
|
||||
// open the loop track
|
||||
if(!S_OpenBackgroundTrack(s_bgTrack.loopName, &s_bgTrack))
|
||||
{
|
||||
S_StopBackgroundTrack();
|
||||
return;
|
||||
}
|
||||
s_bgTrack.looping = true;
|
||||
}
|
||||
|
||||
// restart the track, skipping over the header
|
||||
ov_raw_seek(s_bgTrack.vorbisFile, (ogg_int64_t)s_bgTrack.start );
|
||||
|
||||
// try streaming again
|
||||
read = ov_read( s_bgTrack.vorbisFile, data + size, BUFFER_SIZE - size, 0, 2, 1, &dummy );
|
||||
}
|
||||
if( read <= 0 )
|
||||
{
|
||||
// an error occurred
|
||||
S_StopBackgroundTrack();
|
||||
return;
|
||||
}
|
||||
size += read;
|
||||
}
|
||||
|
||||
// upload and queue the new buffer
|
||||
palGenBuffers( 1, &buffer );
|
||||
palBufferData( buffer, s_bgTrack.format, data, size, s_bgTrack.rate );
|
||||
palSourceQueueBuffers( s_streamingChannel->sourceNum, 1, &buffer );
|
||||
queued++;
|
||||
}
|
||||
|
||||
// update volume
|
||||
palSourcef( s_streamingChannel->sourceNum, AL_GAIN, s_musicVolume->value );
|
||||
|
||||
// if not playing, then do so
|
||||
palGetSourcei( s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state );
|
||||
if( state != AL_PLAYING ) palSourcePlay(s_streamingChannel->sourceNum);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartBackgroundTrack
|
||||
=================
|
||||
*/
|
||||
void S_StartBackgroundTrack( const char *introTrack, const char *loopTrack )
|
||||
{
|
||||
if( !al_state.initialized ) return;
|
||||
|
||||
// stop any playing tracks
|
||||
S_StopBackgroundTrack();
|
||||
|
||||
// Start it up
|
||||
com.snprintf( s_bgTrack.introName, sizeof(s_bgTrack.introName), "music/%s.ogg", introTrack);
|
||||
com.snprintf( s_bgTrack.loopName, sizeof(s_bgTrack.loopName), "music/%s.ogg", loopTrack );
|
||||
|
||||
S_StartStreaming();
|
||||
|
||||
// open the intro track
|
||||
if(!S_OpenBackgroundTrack( s_bgTrack.introName, &s_bgTrack))
|
||||
{
|
||||
S_StopBackgroundTrack();
|
||||
return;
|
||||
}
|
||||
S_StreamBackgroundTrack();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StopBackgroundTrack
|
||||
=================
|
||||
*/
|
||||
void S_StopBackgroundTrack( void )
|
||||
{
|
||||
if( !al_state.initialized ) return;
|
||||
|
||||
S_StopStreaming();
|
||||
S_CloseBackgroundTrack(&s_bgTrack);
|
||||
memset(&s_bgTrack, 0, sizeof(bg_track_t));
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StartStreaming
|
||||
=================
|
||||
*/
|
||||
void S_StartStreaming( void )
|
||||
{
|
||||
if( !al_state.initialized ) return;
|
||||
if( s_streamingChannel ) return; // already started
|
||||
|
||||
s_streamingChannel = S_PickChannel( 0, 0 );
|
||||
if( !s_streamingChannel ) return;
|
||||
|
||||
s_streamingChannel->streaming = true;
|
||||
|
||||
// FIXME: OpenAL bug?
|
||||
//palDeleteSources(1, &s_streamingChannel->sourceNum);
|
||||
//palGenSources(1, &s_streamingChannel->sourceNum);
|
||||
|
||||
// set up the source
|
||||
palSourcei(s_streamingChannel->sourceNum, AL_BUFFER, 0 );
|
||||
palSourcei(s_streamingChannel->sourceNum, AL_LOOPING, 0 );
|
||||
palSourcei(s_streamingChannel->sourceNum, AL_SOURCE_RELATIVE, 1 );
|
||||
palSourcefv(s_streamingChannel->sourceNum, AL_POSITION, vec3_origin);
|
||||
palSourcefv(s_streamingChannel->sourceNum, AL_VELOCITY, vec3_origin);
|
||||
palSourcef(s_streamingChannel->sourceNum, AL_REFERENCE_DISTANCE, 1.0);
|
||||
palSourcef(s_streamingChannel->sourceNum, AL_MAX_DISTANCE, 1.0);
|
||||
palSourcef(s_streamingChannel->sourceNum, AL_ROLLOFF_FACTOR, 0.0);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StopStreaming
|
||||
=================
|
||||
*/
|
||||
void S_StopStreaming( void )
|
||||
{
|
||||
int processed;
|
||||
uint buffer;
|
||||
|
||||
if( !al_state.initialized ) return;
|
||||
if( !s_streamingChannel ) return; // already stopped
|
||||
|
||||
s_streamingChannel->streaming = false;
|
||||
// clean up the source
|
||||
palSourceStop(s_streamingChannel->sourceNum);
|
||||
|
||||
palGetSourcei(s_streamingChannel->sourceNum, AL_BUFFERS_PROCESSED, &processed);
|
||||
if( processed > 0 )
|
||||
{
|
||||
while( processed-- )
|
||||
{
|
||||
palSourceUnqueueBuffers(s_streamingChannel->sourceNum, 1, &buffer);
|
||||
palDeleteBuffers(1, &buffer);
|
||||
}
|
||||
}
|
||||
|
||||
palSourcei(s_streamingChannel->sourceNum, AL_BUFFER, 0);
|
||||
|
||||
// FIXME: OpenAL bug?
|
||||
//palDeleteSources(1, &s_streamingChannel->sourceNum);
|
||||
//palGenSources(1, &s_streamingChannel->sourceNum);
|
||||
s_streamingChannel = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
S_StreamRawSamples
|
||||
|
||||
Cinematic streaming
|
||||
=================
|
||||
*/
|
||||
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data )
|
||||
{
|
||||
int processed, state, size;
|
||||
uint format, buffer;
|
||||
|
||||
if( !al_state.initialized ) return;
|
||||
if( !s_streamingChannel ) return;
|
||||
|
||||
// unqueue and delete any processed buffers
|
||||
palGetSourcei( s_streamingChannel->sourceNum, AL_BUFFERS_PROCESSED, &processed );
|
||||
if( processed > 0 )
|
||||
{
|
||||
while( processed-- )
|
||||
{
|
||||
palSourceUnqueueBuffers(s_streamingChannel->sourceNum, 1, &buffer);
|
||||
palDeleteBuffers(1, &buffer);
|
||||
}
|
||||
}
|
||||
|
||||
// calculate buffer size
|
||||
size = samples * width * channels;
|
||||
|
||||
// set buffer format
|
||||
if( width == 2 )
|
||||
{
|
||||
if( channels == 2 ) format = AL_FORMAT_STEREO16;
|
||||
else format = AL_FORMAT_MONO16;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( channels == 2 ) format = AL_FORMAT_STEREO8;
|
||||
else format = AL_FORMAT_MONO8;
|
||||
}
|
||||
|
||||
// upload and queue the new buffer
|
||||
palGenBuffers( 1, &buffer );
|
||||
palBufferData( buffer, format, (byte *)data, size, rate );
|
||||
palSourceQueueBuffers( s_streamingChannel->sourceNum, 1, &buffer );
|
||||
|
||||
// update volume
|
||||
palSourcef( s_streamingChannel->sourceNum, AL_GAIN, s_sfxVolume->value );
|
||||
|
||||
// if not playing, then do so
|
||||
palGetSourcei(s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state);
|
||||
if( state != AL_PLAYING ) palSourcePlay( s_streamingChannel->sourceNum );
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// s_openal.h - openal definition
|
||||
//=======================================================================
|
||||
|
||||
#ifndef S_STREAM_H
|
||||
#define S_STREAM_H
|
||||
|
||||
typedef __int64 ogg_int64_t;
|
||||
typedef __int32 ogg_int32_t;
|
||||
typedef unsigned __int32 ogg_uint32_t;
|
||||
typedef __int16 ogg_int16_t;
|
||||
typedef unsigned __int16 ogg_uint16_t;
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
OGG PACK DEFINITION
|
||||
=======================================================================
|
||||
*/
|
||||
struct ogg_chain_s
|
||||
{
|
||||
void *ptr;
|
||||
struct alloc_chain *next;
|
||||
};
|
||||
|
||||
typedef struct oggpack_buffer_s
|
||||
{
|
||||
long endbyte;
|
||||
int endbit;
|
||||
byte *buffer;
|
||||
byte *ptr;
|
||||
long storage;
|
||||
} oggpack_buffer_t;
|
||||
|
||||
typedef struct ogg_sync_state_s
|
||||
{
|
||||
byte *data;
|
||||
int storage;
|
||||
int fill;
|
||||
int returned;
|
||||
int unsynced;
|
||||
int headerbytes;
|
||||
int bodybytes;
|
||||
} ogg_sync_state_t;
|
||||
|
||||
typedef struct ogg_stream_state_s
|
||||
{
|
||||
byte *body_data;
|
||||
long body_storage;
|
||||
long body_fill;
|
||||
long body_returned;
|
||||
int *lacing_vals;
|
||||
ogg_int64_t *granule_vals;
|
||||
long lacing_storage;
|
||||
long lacing_fill;
|
||||
long lacing_packet;
|
||||
long lacing_returned;
|
||||
byte header[282];
|
||||
int header_fill;
|
||||
int e_o_s;
|
||||
int b_o_s;
|
||||
long serialno;
|
||||
long pageno;
|
||||
ogg_int64_t packetno;
|
||||
ogg_int64_t granulepos;
|
||||
} ogg_stream_state_t;
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
VORBIS FILE DEFINITION
|
||||
=======================================================================
|
||||
*/
|
||||
typedef struct vorbis_info_s
|
||||
{
|
||||
int version;
|
||||
int channels;
|
||||
long rate;
|
||||
long bitrate_upper;
|
||||
long bitrate_nominal;
|
||||
long bitrate_lower;
|
||||
long bitrate_window;
|
||||
void *codec_setup;
|
||||
} vorbis_info_t;
|
||||
|
||||
typedef struct vorbis_comment_s
|
||||
{
|
||||
char **user_comments;
|
||||
int *comment_lengths;
|
||||
int comments;
|
||||
char *vendor;
|
||||
} vorbis_comment_t;
|
||||
|
||||
typedef struct vorbis_dsp_state_s
|
||||
{
|
||||
int analysisp;
|
||||
vorbis_info_t *vi;
|
||||
float **pcm;
|
||||
float **pcmret;
|
||||
int pcm_storage;
|
||||
int pcm_current;
|
||||
int pcm_returned;
|
||||
int preextrapolate;
|
||||
int eofflag;
|
||||
long lW;
|
||||
long W;
|
||||
long nW;
|
||||
long centerW;
|
||||
ogg_int64_t granulepos;
|
||||
ogg_int64_t sequence;
|
||||
ogg_int64_t glue_bits;
|
||||
ogg_int64_t time_bits;
|
||||
ogg_int64_t floor_bits;
|
||||
ogg_int64_t res_bits;
|
||||
void *backend_state;
|
||||
} vorbis_dsp_state_t;
|
||||
|
||||
typedef struct vorbis_block_s
|
||||
{
|
||||
float **pcm;
|
||||
oggpack_buffer_t opb;
|
||||
long lW;
|
||||
long W;
|
||||
long nW;
|
||||
int pcmend;
|
||||
int mode;
|
||||
int eofflag;
|
||||
ogg_int64_t granulepos;
|
||||
ogg_int64_t sequence;
|
||||
vorbis_dsp_state_t *vd;
|
||||
void *localstore;
|
||||
long localtop;
|
||||
long localalloc;
|
||||
long totaluse;
|
||||
struct ogg_chain_s *reap;
|
||||
long glue_bits;
|
||||
long time_bits;
|
||||
long floor_bits;
|
||||
long res_bits;
|
||||
void *internal;
|
||||
} vorbis_block_t;
|
||||
|
||||
typedef struct ov_callbacks_s
|
||||
{
|
||||
size_t (*read_func)( void *ptr, size_t size, size_t nmemb, void *datasource );
|
||||
int (*seek_func)( void *datasource, ogg_int64_t offset, int whence );
|
||||
int (*close_func)( void *datasource );
|
||||
long (*tell_func)( void *datasource );
|
||||
} ov_callbacks_t;
|
||||
|
||||
typedef struct vorbisfile_s
|
||||
{
|
||||
void *datasource;
|
||||
int seekable;
|
||||
ogg_int64_t offset;
|
||||
ogg_int64_t end;
|
||||
ogg_sync_state_t oy;
|
||||
int links;
|
||||
ogg_int64_t *offsets;
|
||||
ogg_int64_t *dataoffsets;
|
||||
long *serialnos;
|
||||
ogg_int64_t *pcmlengths;
|
||||
vorbis_info_t *vi;
|
||||
vorbis_comment_t *vc;
|
||||
ogg_int64_t pcm_offset;
|
||||
int ready_state;
|
||||
long current_serialno;
|
||||
int current_link;
|
||||
double bittrack;
|
||||
double samptrack;
|
||||
ogg_stream_state_t os;
|
||||
vorbis_dsp_state_t vd;
|
||||
vorbis_block_t vb;
|
||||
ov_callbacks_t callbacks;
|
||||
|
||||
} vorbisfile_t;
|
||||
|
||||
// libvorbis exports
|
||||
int ov_open_callbacks( void *datasource, vorbisfile_t *vf, char *initial, long ibytes, ov_callbacks_t callbacks );
|
||||
long ov_read( vorbisfile_t *vf, char *buffer, int length, int bigendianp, int word, int sgned, int *bitstream );
|
||||
vorbis_info_t *ov_info( vorbisfile_t *vf, int link );
|
||||
int ov_raw_seek( vorbisfile_t *vf, ogg_int64_t pos );
|
||||
ogg_int64_t ov_raw_tell( vorbisfile_t *vf );
|
||||
int ov_clear( vorbisfile_t *vf);
|
||||
|
||||
#endif//S_STREAM_H
|
|
@ -1,11 +1,9 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// cl_sound.c - sound engine
|
||||
// snd_main.c - sound engine
|
||||
//=======================================================================
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include <dsound.h>
|
||||
#include "sound.h"
|
||||
|
||||
#define PAINTBUFFER_SIZE 4096 // this is in samples
|
||||
|
||||
|
@ -145,6 +143,9 @@ void SND_free(sndBuffer *v);
|
|||
sndBuffer* SND_malloc();
|
||||
void SND_setup();
|
||||
|
||||
HWND hWnd;
|
||||
uint framecount = 0;
|
||||
|
||||
void S_PaintChannels(int endtime);
|
||||
|
||||
void S_memoryLoad(sfx_t *sfx);
|
||||
|
@ -231,7 +232,7 @@ void SNDDMA_Shutdown( void )
|
|||
if ( pDS )
|
||||
{
|
||||
MsgDev(D_INFO, "...setting NORMAL coop level\n" );
|
||||
pDS->lpVtbl->SetCooperativeLevel( pDS, host.hWnd, DSSCL_PRIORITY );
|
||||
pDS->lpVtbl->SetCooperativeLevel( pDS, hWnd, DSSCL_PRIORITY );
|
||||
}
|
||||
|
||||
if ( pDSBuf )
|
||||
|
@ -289,7 +290,7 @@ int SNDDMA_InitDS( void )
|
|||
MsgDev(D_INFO, "ok\n" );
|
||||
|
||||
MsgDev(D_INFO, "...setting DSSCL_PRIORITY coop level: " );
|
||||
if(DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, host.hWnd, DSSCL_PRIORITY ))
|
||||
if(DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, hWnd, DSSCL_PRIORITY ))
|
||||
{
|
||||
MsgDev(D_INFO, "failed\n");
|
||||
SNDDMA_Shutdown ();
|
||||
|
@ -489,7 +490,7 @@ void SNDDMA_Activate( void )
|
|||
{
|
||||
if( !pDS ) return;
|
||||
|
||||
if( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, host.hWnd, DSSCL_PRIORITY ))
|
||||
if( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, hWnd, DSSCL_PRIORITY ))
|
||||
{
|
||||
MsgDev(D_INFO, "sound SetCooperativeLevel failed\n");
|
||||
SNDDMA_Shutdown();
|
||||
|
@ -586,10 +587,12 @@ void S_SoundInfo_f( void )
|
|||
S_Init
|
||||
================
|
||||
*/
|
||||
void S_Init( void )
|
||||
void S_Init( void *hInst )
|
||||
{
|
||||
cvar_t *cv;
|
||||
|
||||
S_Init_OpenAL();
|
||||
|
||||
s_volume = Cvar_Get ("s_volume", "0.8", CVAR_ARCHIVE);
|
||||
s_musicVolume = Cvar_Get ("s_musicvolume", "0.25", CVAR_ARCHIVE);
|
||||
s_separation = Cvar_Get ("s_separation", "0.5", CVAR_ARCHIVE);
|
||||
|
@ -609,6 +612,10 @@ void S_Init( void )
|
|||
Cmd_AddCommand("snd_info", S_SoundInfo_f, "print sound system information" );
|
||||
Cmd_AddCommand("snd_stop", S_StopAllSounds, "stop all sounds" );
|
||||
|
||||
hWnd = hInst;
|
||||
|
||||
sndpool = Mem_AllocPool("Sound Zone");
|
||||
|
||||
if (SNDDMA_Init())
|
||||
{
|
||||
s_soundStarted = 1;
|
||||
|
@ -663,8 +670,9 @@ void S_Shutdown( void )
|
|||
{
|
||||
if ( !s_soundStarted ) return;
|
||||
SNDDMA_Shutdown();
|
||||
s_soundStarted = 0;
|
||||
Mem_FreePool( &sndpool );
|
||||
|
||||
s_soundStarted = 0;
|
||||
Cmd_RemoveCommand("play");
|
||||
Cmd_RemoveCommand("music");
|
||||
Cmd_RemoveCommand("stopsound");
|
||||
|
@ -940,7 +948,7 @@ if pos is NULL, the sound will be dynamically sourced from the entity
|
|||
Entchannel 0 will never override a playing sound
|
||||
====================
|
||||
*/
|
||||
void S_StartSound(vec3_t origin, int entityNum, int entchannel, sound_t sfxHandle )
|
||||
void S_StartSound( const vec3_t origin, int entityNum, int entchannel, sound_t sfxHandle, float vol, float attn )
|
||||
{
|
||||
channel_t *ch;
|
||||
sfx_t *sfx;
|
||||
|
@ -1075,7 +1083,7 @@ int S_StartLocalSound( const char *name )
|
|||
return false;
|
||||
}
|
||||
|
||||
S_StartSound (NULL, listener_number, CHAN_AUTO, sfxHandle );
|
||||
S_StartSound (NULL, listener_number, CHAN_AUTO, sfxHandle, ATTN_NORM, 1.0f );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1205,14 +1213,14 @@ void S_AddLoopingSound( int entityNum, const vec3_t origin, const vec3_t velocit
|
|||
lena = VectorDistance2(loopSounds[listener_number].origin, loopSounds[entityNum].origin);
|
||||
VectorAdd(loopSounds[entityNum].origin, loopSounds[entityNum].velocity, out);
|
||||
lenb = VectorDistance2(loopSounds[listener_number].origin, out);
|
||||
if ((loopSounds[entityNum].framenum + 1) != cls.framecount)
|
||||
if ((loopSounds[entityNum].framenum + 1) != framecount)
|
||||
loopSounds[entityNum].oldDopplerScale = 1.0;
|
||||
else loopSounds[entityNum].oldDopplerScale = loopSounds[entityNum].dopplerScale;
|
||||
loopSounds[entityNum].dopplerScale = lenb/(lena * 100);
|
||||
if (loopSounds[entityNum].dopplerScale<=1.0)
|
||||
loopSounds[entityNum].doppler = false; // don't bother doing the math
|
||||
}
|
||||
loopSounds[entityNum].framenum = cls.framecount;
|
||||
loopSounds[entityNum].framenum = framecount;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1464,7 +1472,7 @@ S_Respatialize
|
|||
Change the volumes of all the playing sounds for changes in their positions
|
||||
============
|
||||
*/
|
||||
void S_Respatialize( int entityNum, const vec3_t head, vec3_t v_forward, vec3_t v_right, vec3_t v_up )
|
||||
void S_Respatialize( int entityNum, const vec3_t head, const vec3_t v_forward, const vec3_t v_right, const vec3_t v_up )
|
||||
{
|
||||
int i;
|
||||
channel_t *ch;
|
||||
|
@ -1665,36 +1673,6 @@ console functions
|
|||
|
||||
===============================================================================
|
||||
*/
|
||||
void S_Play_f( void )
|
||||
{
|
||||
int i = 1;
|
||||
char name[256];
|
||||
|
||||
while ( i < Cmd_Argc())
|
||||
{
|
||||
if ( !com.strrchr(Cmd_Argv(i), '.')) com.sprintf( name, "%s.wav", Cmd_Argv(1) );
|
||||
else com.strncpy( name, Cmd_Argv(i), sizeof(name) );
|
||||
S_StartLocalSound( name );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void S_Music_f( void )
|
||||
{
|
||||
int c = Cmd_Argc();
|
||||
|
||||
if ( c == 2 )
|
||||
{
|
||||
S_StartBackgroundTrack( Cmd_Argv(1), Cmd_Argv(1) );
|
||||
s_backgroundLoop[0] = 0;
|
||||
}
|
||||
else if ( c == 3 )
|
||||
{
|
||||
S_StartBackgroundTrack( Cmd_Argv(1), Cmd_Argv(2) );
|
||||
}
|
||||
else Msg("music <musicfile> [loopfile]\n");
|
||||
}
|
||||
|
||||
void S_SoundList_f( void )
|
||||
{
|
||||
sfx_t *sfx;
|
||||
|
@ -2264,11 +2242,11 @@ of a forced fallback of a player specific sound
|
|||
*/
|
||||
bool S_LoadSound( sfx_t *sfx )
|
||||
{
|
||||
byte *data;
|
||||
short *samples;
|
||||
wavinfo_t info;
|
||||
int size;
|
||||
char namebuffer[MAX_QPATH];
|
||||
byte *data;
|
||||
short *samples;
|
||||
wavinfo_t info;
|
||||
int size;
|
||||
string namebuffer;
|
||||
|
||||
// player specific sounds are never directly loaded
|
||||
if ( sfx->soundName[0] == '*') return false;
|
|
@ -0,0 +1,207 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// sound.h - sndlib main header
|
||||
//=======================================================================
|
||||
|
||||
#ifndef SOUND_H
|
||||
#define SOUND_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <dsound.h>
|
||||
#include "basetypes.h"
|
||||
#include "stdapi.h"
|
||||
#include "stdref.h"
|
||||
#include "basefiles.h"
|
||||
#include "dllapi.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
#include "s_openal.h"
|
||||
|
||||
extern stdlib_api_t com;
|
||||
extern vsound_imp_t si;
|
||||
extern byte *sndpool;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int rate;
|
||||
int width;
|
||||
int channels;
|
||||
int samples;
|
||||
} wavinfo_t;
|
||||
|
||||
typedef struct sfx_s
|
||||
{
|
||||
string name;
|
||||
bool default_snd;
|
||||
bool loaded;
|
||||
int samples;
|
||||
int rate;
|
||||
uint format;
|
||||
uint bufferNum;
|
||||
|
||||
struct sfx_s *nextHash;
|
||||
} sfx_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string introName;
|
||||
string loopName;
|
||||
bool looping;
|
||||
file_t *file;
|
||||
int start;
|
||||
int rate;
|
||||
uint format;
|
||||
void *vorbisFile;
|
||||
} bg_track_t;
|
||||
|
||||
// A playSound will be generated by each call to S_StartSound.
|
||||
// When the mixer reaches playSound->beginTime, the playSound will be
|
||||
// assigned to a channel.
|
||||
typedef struct playsound_s
|
||||
{
|
||||
struct playsound_s *prev, *next;
|
||||
sfx_t *sfx;
|
||||
int entnum;
|
||||
int entchannel;
|
||||
bool fixedPosition; // Use position instead of fetching entity's origin
|
||||
vec3_t position; // Only use if fixedPosition is set
|
||||
float volume;
|
||||
float attenuation;
|
||||
int beginTime; // Begin at this time
|
||||
} playSound_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool streaming;
|
||||
sfx_t *sfx; // NULL if unused
|
||||
int entnum; // To allow overriding a specific sound
|
||||
int entchannel;
|
||||
int startTime; // For overriding oldest sounds
|
||||
bool loopsound; // Looping sound
|
||||
int loopnum; // Looping entity number
|
||||
int loopframe; // For stopping looping sounds
|
||||
bool fixedPosition; // Use position instead of fetching entity's origin
|
||||
vec3_t position; // Only use if fixedPosition is set
|
||||
float volume;
|
||||
float distanceMult;
|
||||
uint sourceNum; // OpenAL source
|
||||
} channel_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t position;
|
||||
vec3_t velocity;
|
||||
float orientation[6];
|
||||
} listener_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char *vendor_string;
|
||||
const char *renderer_string;
|
||||
const char *version_string;
|
||||
const char *extensions_string;
|
||||
|
||||
string deviceList[4];
|
||||
const char *defDevice;
|
||||
uint device_count;
|
||||
uint num_slots;
|
||||
uint num_sends;
|
||||
|
||||
bool allow_3DMode;
|
||||
|
||||
// 3d mode extension (eax or i3d)
|
||||
int (*Set3DMode)( const guid_t*, uint, uint, void*, uint );
|
||||
int (*Get3DMode)( const guid_t*, uint, uint, void*, uint );
|
||||
} alconfig_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
aldevice *hDevice;
|
||||
alcontext *hALC;
|
||||
|
||||
bool initialized;
|
||||
bool active;
|
||||
uint framecount;
|
||||
int num_channels;
|
||||
int clientnum;
|
||||
} alstate_t;
|
||||
|
||||
extern alconfig_t al_config;
|
||||
extern alstate_t al_state;
|
||||
|
||||
#define Host_Error com.error
|
||||
|
||||
#define Z_Malloc( size ) Mem_Alloc( sndpool, size )
|
||||
|
||||
// cvars
|
||||
extern cvar_t *s_initSound;
|
||||
extern cvar_t *s_show;
|
||||
extern cvar_t *s_alDevice;
|
||||
extern cvar_t *s_allowExtensions;
|
||||
extern cvar_t *s_soundfx;
|
||||
extern cvar_t *s_ignoreALErrors;
|
||||
extern cvar_t *s_masterVolume;
|
||||
extern cvar_t *s_sfxVolume;
|
||||
extern cvar_t *s_musicVolume;
|
||||
extern cvar_t *s_minDistance;
|
||||
extern cvar_t *s_maxDistance;
|
||||
extern cvar_t *s_rolloffFactor;
|
||||
extern cvar_t *s_dopplerFactor;
|
||||
extern cvar_t *s_dopplerVelocity;
|
||||
|
||||
|
||||
extern int s_rawend;
|
||||
extern int s_soundtime;
|
||||
|
||||
void S_Init( void *hInst );
|
||||
void S_Shutdown( void );
|
||||
|
||||
void S_Activate( bool active );
|
||||
void S_SoundList_f( void );
|
||||
|
||||
// if origin is NULL, the sound will be dynamically sourced from the entity
|
||||
void S_StartSound( const vec3_t origin, int entnum, int entchannel, sound_t sfx, float vol, float attn );
|
||||
int S_StartLocalSound( const char *name );
|
||||
void S_StartBackgroundTrack( const char *intro, const char *loop );
|
||||
void S_StopBackgroundTrack( void );
|
||||
sfx_t *S_GetSfxByHandle( sound_t handle );
|
||||
bool S_LoadSound( sfx_t *sfx );
|
||||
channel_t *S_PickChannel( int entNum, int entChannel );
|
||||
|
||||
void S_StartStreaming( void );
|
||||
void S_StreamBackgroundTrack( void );
|
||||
void S_StopStreaming( void );
|
||||
|
||||
// cinematics and voice-over-network will send raw samples
|
||||
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
|
||||
|
||||
// stop all sounds and the background track
|
||||
void S_StopAllSounds( void );
|
||||
void S_FreeSounds( void );
|
||||
|
||||
// all continuous looping sounds must be added before calling S_Update
|
||||
bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn );
|
||||
void S_StopLoopingSound(int entityNum );
|
||||
|
||||
// recompute the reletive volumes for all running sounds
|
||||
// reletive to the given entityNum / orientation
|
||||
void S_Respatialize( int entityNum, const vec3_t origin, const vec3_t v_forward, const vec3_t v_left, const vec3_t v_up );
|
||||
|
||||
// let the sound system know where an entity currently is
|
||||
void S_UpdateEntityPosition( int entityNum, const vec3_t origin );
|
||||
void S_Update( int clientnum, const vec3_t pos, const vec3_t vel, const vec3_t at, const vec3_t up );
|
||||
void S_DisableSounds( void );
|
||||
void S_EnableSounds( void );
|
||||
void S_BeginRegistration( void );
|
||||
void S_EndRegistration( void );
|
||||
|
||||
// RegisterSound will allways return a valid sample, even if it
|
||||
// has to create a placeholder. This prevents continuous filesystem
|
||||
// checks for missing files
|
||||
sound_t S_RegisterSound( const char *sample );
|
||||
void S_DisplayFreeMemory(void);
|
||||
void S_ClearSoundBuffer( void );
|
||||
void SNDDMA_Activate( void );
|
||||
void S_UpdateBackgroundTrack( void );
|
||||
|
||||
#endif//SOUND_H
|
Binary file not shown.
|
@ -0,0 +1,148 @@
|
|||
# Microsoft Developer Studio Project File - Name="vsound" - 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
|
||||
!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
|
||||
!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
|
||||
!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
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "vsound - 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\vsound\!release"
|
||||
# PROP Intermediate_Dir "..\temp\vsound\!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" /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 libogg.lib vorbis.lib /nologo /dll /profile /machine:I386 /nodefaultlib:"libcmt.lib" /opt:nowin98
|
||||
# Begin Custom Build
|
||||
TargetDir=\Xash3D\src_main\temp\vsound\!release
|
||||
InputPath=\Xash3D\src_main\temp\vsound\!release\vsound.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\vsound.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\vsound.dll "D:\Xash3D\bin\vsound.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "vsound - 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\vsound\!debug"
|
||||
# PROP Intermediate_Dir "..\temp\vsound\!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 /I "./" /I "../public" /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 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
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"D:\Xash3D\bin\vsound.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetDir)\vsound.dll "D:\Xash3D\bin\vsound.dll"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "vsound - Win32 Release"
|
||||
# Name "vsound - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# 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_openal.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\s_stream.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\s_export.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
|
13
xash.dsw
13
xash.dsw
|
@ -61,6 +61,19 @@ Package=<4>
|
|||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "vsound"=".\vsound\vsound.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "engine"=".\engine\engine.dsp" - Package Owner=<4>
|
||||
|
|
Reference in New Issue