diff --git a/common/bsplib/bspfile.c b/common/bsplib/bspfile.c index ec621f97..f526105b 100644 --- a/common/bsplib/bspfile.c +++ b/common/bsplib/bspfile.c @@ -217,6 +217,8 @@ void SwapBSPFile( bool todisk ) bool CompressLump( const char *lumpname, size_t length ) { + if( !bsplib_compress_bsp->integer ) + return false; if( !com.strcmp( lumpname, LUMP_MAPINFO )) return false; if( !com.strcmp( lumpname, LUMP_ENTITIES )) diff --git a/common/bsplib/bsplib.c b/common/bsplib/bsplib.c index cc535f80..0f21a3c6 100644 --- a/common/bsplib/bsplib.c +++ b/common/bsplib/bsplib.c @@ -10,6 +10,7 @@ size_t checkermate_dds_size; char path[MAX_SYSPATH]; uint bsp_parms; file_t *bsplog; +cvar_t *bsplib_compress_bsp; dll_info_t physic_dll = { "physic.dll", NULL, "CreateAPI", NULL, NULL, false, sizeof(physic_exp_t) }; physic_exp_t *pe; @@ -82,6 +83,7 @@ bool PrepareBSPModel( const char *dir, const char *name ) // famous q1 "notexture" image: purple-black checkerboard checkermate_dds = FS_LoadInternal( "checkerboard.dds", &checkermate_dds_size ); Image_Init( NULL, IL_ALLOW_OVERWRITE|IL_IGNORE_MIPS ); + bsplib_compress_bsp = Cvar_Get( "bsp_compress", "0", CVAR_SYSTEMINFO, "compress bsp lumps" ); // merge parms if( bsp_parms & BSPLIB_ONLYENTS ) diff --git a/common/bsplib/bsplib.h b/common/bsplib/bsplib.h index bd4e4061..75492bfc 100644 --- a/common/bsplib/bsplib.h +++ b/common/bsplib/bsplib.h @@ -56,6 +56,7 @@ typedef enum extern uint bsp_parms; extern physic_exp_t *pe; extern char path[MAX_SYSPATH]; +extern cvar_t *bsplib_compress_bsp; // bsplib export functions void WradMain( void ); diff --git a/common/platform.c b/common/platform.c index 33172b9f..de745697 100644 --- a/common/platform.c +++ b/common/platform.c @@ -7,6 +7,7 @@ #include "utils.h" #include "bsplib.h" #include "mdllib.h" +#include "vprogs_api.h" dll_info_t vprogs_dll = { "vprogs.dll", NULL, "CreateAPI", NULL, NULL, true, sizeof(vprogs_exp_t) }; vprogs_exp_t *PRVM; diff --git a/common/platform.h b/common/platform.h index 9d3dc22b..a59db6cc 100644 --- a/common/platform.h +++ b/common/platform.h @@ -8,7 +8,6 @@ #include #include "launch_api.h" #include "qfiles_ref.h" -#include "vprogs_api.h" //===================================== // platform export diff --git a/common/ripper/ripper.h b/common/ripper/ripper.h index 4a59eb3f..18627f9d 100644 --- a/common/ripper/ripper.h +++ b/common/ripper/ripper.h @@ -11,7 +11,6 @@ extern stdlib_api_t com; extern byte *basepool; extern string gs_gamedir; #define Sys_Error com.error -extern vprogs_exp_t *PRVM; extern uint app_name; extern bool write_qscsript; extern int game_family; diff --git a/common/utils.h b/common/utils.h index b486e756..0c74d79d 100644 --- a/common/utils.h +++ b/common/utils.h @@ -14,7 +14,6 @@ extern byte *basepool; extern byte *zonepool; extern bool enable_log; extern stdlib_api_t com; -extern vprogs_exp_t *PRVM; #define Sys_Error com.error #define Malloc(size) Mem_Alloc( basepool, size ) diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 76dc733f..7a436b50 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -237,10 +237,35 @@ void CL_ParseConfigString( sizebuf_t *msg ) CL_VM_Begin(); // do something apropriate - if( i >= CS_SKYNAME && i < CS_MAXCLIENTS && cl.video_prepped ) + if( i == CS_SKYNAME && cl.video_prepped ) { re->RegisterShader( cl.configstrings[CS_SKYNAME], SHADER_SKY ); } + else if( i == CS_BACKGROUND_TRACK && cl.audio_prepped ) + { + string intro, main, track; + + // build fullnames + com.strncpy( track, cl.configstrings[CS_BACKGROUND_TRACK], MAX_STRING ); + com.snprintf( intro, MAX_STRING, "%s_intro", cl.configstrings[CS_BACKGROUND_TRACK] ); + com.snprintf( main, MAX_STRING, "%s_main", cl.configstrings[CS_BACKGROUND_TRACK] ); + + if( FS_FileExists( va( "media/%s.ogg", intro )) && FS_FileExists( va( "media/%s.ogg", main ))) + { + // combined track with introduction and main loop theme + S_StartBackgroundTrack( intro, main ); + } + else if( FS_FileExists( va( "media/%s.ogg", track ))) + { + // single looped theme + S_StartBackgroundTrack( track, track ); + } + else if( !com.strcmp( track, "" )) + { + // blank name stopped last track + S_StopBackgroundTrack(); + } + } else if( i >= CS_MODELS && i < CS_MODELS+MAX_MODELS && cl.video_prepped ) { re->RegisterModel( cl.configstrings[i], i-CS_MODELS ); diff --git a/engine/client/cl_progs.c b/engine/client/cl_progs.c index 027ace65..700ddc5f 100644 --- a/engine/client/cl_progs.c +++ b/engine/client/cl_progs.c @@ -232,6 +232,7 @@ static void PF_EndRead( void ) } static void PF_ReadChar (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadChar( cls.multicast ); } +static void PF_ReadByte (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadByte( cls.multicast ); } static void PF_ReadShort (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadShort( cls.multicast ); } static void PF_ReadLong (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadLong( cls.multicast ); } static void PF_ReadFloat (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadFloat( cls.multicast ); } @@ -488,7 +489,7 @@ static void PF_setcolor( void ) ========= PF_startsound -void CL_StartSound( vector pos, entity e, float chan, float sfx, float vol, float attn, float localsound ) +void CL_StartSound( vector pos, entity e, float chan, float sfx, float vol, float attn, float pitch, float localsound ) ========= */ static void PF_startsound( void ) @@ -500,8 +501,9 @@ static void PF_startsound( void ) float *pos = NULL; bool client_sound; int ent = 0; + float pitch; - if( !VM_ValidateArgs( "CL_StartSound", 7 )) + if( !VM_ValidateArgs( "CL_StartSound", 8 )) return; pos = PRVM_G_VECTOR(OFS_PARM0); @@ -510,15 +512,16 @@ static void PF_startsound( void ) sound_num = (sound_t)PRVM_G_FLOAT(OFS_PARM3); volume = PRVM_G_FLOAT(OFS_PARM4); attenuation = (int)PRVM_G_FLOAT(OFS_PARM5); - client_sound = (bool)PRVM_G_FLOAT(OFS_PARM6); + pitch = (int)PRVM_G_FLOAT(OFS_PARM6); + client_sound = (bool)PRVM_G_FLOAT(OFS_PARM7); if( client_sound ) { - S_StartSound( pos, ent, channel, sound_num, volume, attenuation ); + S_StartSound( pos, ent, channel, sound_num, volume, attenuation, pitch ); } else if( cl.sound_precache[sound_num] ) { - S_StartSound( pos, ent, channel, cl.sound_precache[sound_num], volume, attenuation ); + S_StartSound( pos, ent, channel, cl.sound_precache[sound_num], volume, attenuation, pitch ); } else VM_Warning( "CL_StartSound: can't play sound with index %i\n", sound_num ); } @@ -691,15 +694,15 @@ e10, e10, // #81 - #100 are reserved for future expansions // network messaging PF_BeginRead, // #101 void MsgBegin( void ) -NULL, // #102 -PF_ReadChar, // #103 float ReadChar (float f) -PF_ReadShort, // #104 float ReadShort (float f) -PF_ReadLong, // #105 float ReadLong (float f) -PF_ReadFloat, // #106 float ReadFloat (float f) -PF_ReadAngle, // #107 float ReadAngle (float f) -PF_ReadCoord, // #108 float ReadCoord (float f) -PF_ReadString, // #109 string ReadString (string s) -PF_ReadEntity, // #110 entity ReadEntity (entity s) +PF_ReadByte, // #102 float ReadByte( void ) +PF_ReadChar, // #103 float ReadChar( void ) +PF_ReadShort, // #104 float ReadShort( void ) +PF_ReadLong, // #105 float ReadLong( void ) +PF_ReadFloat, // #106 float ReadFloat( void ) +PF_ReadAngle, // #107 float ReadAngle( void ) +PF_ReadCoord, // #108 float ReadCoord( void ) +PF_ReadString, // #109 string ReadString( void ) +PF_ReadEntity, // #110 entity ReadEntity( void ) PF_EndRead, // #111 void MsgEnd( void ) // clientfuncs_t @@ -718,7 +721,7 @@ PF_centerprint, // #123 void HUD_CenterPrint( string text, float y, float char PF_levelshot, // #124 float HUD_MakeLevelShot( void ) PF_setcolor, // #125 void HUD_SetColor( vector rgb, float alpha ) VM_localsound, // #126 void HUD_PlaySound( string sample ) -PF_startsound, // #127 void CL_StartSound( vector, entity, float, float, float, float, float ) +PF_startsound, // #127 void CL_StartSound( vector, entity, float, float, float, float, float, float ) PF_addparticle, // #128 float AddParticle(vector, vector, vector, vector, vector, vector, vector, string, float) PF_pointcontents, // #129 float CL_PointContents( vector point ) PF_precachesound, // #130 sound_t CL_PrecacheSound( string samp ) diff --git a/engine/client/client.h b/engine/client/client.h index ff0bb367..e72d5e55 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -467,7 +467,7 @@ void CL_VM_End( void ); // if origin is NULL, the sound will be dynamically sourced from the entity #define S_StartStreaming se->StartStreaming #define S_RegisterSound se->RegisterSound -#define S_StartSound( a,b,c,d,e,f ) se->StartSound( a, b, c, d, e, f, true ); +#define S_StartSound( a,b,c,d,e,f,g ) se->StartSound( a, b, c, d, e, f, g, true ); #define S_StartLocalSound se->StartLocalSound #define S_StartBackgroundTrack se->StartBackgroundTrack #define S_StopBackgroundTrack se->StopBackgroundTrack diff --git a/engine/common/engfuncs.c b/engine/common/engfuncs.c index 48a3dee5..b2f0f6bc 100644 --- a/engine/common/engfuncs.c +++ b/engine/common/engfuncs.c @@ -62,6 +62,7 @@ supports follow prefixes: %p - function pointer (will be printed function name) %e - entity (will be print entity number) - just in case %v - vector (format: %g %g %g) +%x - print flags as hexadecimal ========= */ const char *VM_VarArgs( int start_arg ) @@ -78,7 +79,7 @@ const char *VM_VarArgs( int start_arg ) s = PRVM_G_STRING((OFS_PARM0 + start_arg * 3)); out = vm_string; outend = out + MAX_SYSPATH - 1; - memset( vm_string, 0, MAX_SYSPATH - 1 ); + Mem_Set( vm_string, 0, MAX_SYSPATH - 1 ); while( out < outend && *s ) { @@ -93,6 +94,7 @@ const char *VM_VarArgs( int start_arg ) { case 'd': com.snprintf( vm_arg, MAX_STRING, "%d", (int)PRVM_G_FLOAT(OFS_PARM0+arg*3)); break; case 'i': com.snprintf( vm_arg, MAX_STRING, "%i", (int)PRVM_G_FLOAT(OFS_PARM0+arg*3)); break; + case 'x': com.snprintf( vm_arg, MAX_STRING, "%p", (int)PRVM_G_FLOAT(OFS_PARM0+arg*3)); break; case 's': com.snprintf( vm_arg, MAX_STRING, "%s", PRVM_G_STRING(OFS_PARM0+arg*3)); break; case 'f': com.snprintf( vm_arg, MAX_STRING, "%f", PRVM_G_FLOAT(OFS_PARM0+arg*3)); break; case 'g': com.snprintf( vm_arg, MAX_STRING, "%g", PRVM_G_FLOAT(OFS_PARM0+arg*3)); break; diff --git a/engine/common/net_msg.h b/engine/common/net_msg.h index 35a1b412..d877a8ce 100644 --- a/engine/common/net_msg.h +++ b/engine/common/net_msg.h @@ -125,6 +125,7 @@ static const net_desc_t NWDesc[] = #define CS_MAPCHECKSUM 1 // level checksum (for catching cheater maps) #define CS_SKYNAME 2 // skybox shader name #define CS_MAXCLIENTS 3 // server maxclients value (0-255) +#define CS_BACKGROUND_TRACK 4 // basename of background track // reserved config strings diff --git a/engine/server/server.h b/engine/server/server.h index b70680d4..f62d5969 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -261,6 +261,7 @@ extern cvar_t *sv_playersonly; extern cvar_t *sv_rollangle; extern cvar_t *sv_rollspeed; extern cvar_t *sv_maxspeed; +extern cvar_t *sv_physics; extern cvar_t *host_frametime; extern sv_client_t *sv_client; @@ -314,7 +315,7 @@ bool SV_CheckBottom (edict_t *ent); // sv_move.c // void SV_Transform( sv_edict_t *ed, const vec3_t origin, const matrix3x3 transform ); -void SV_PlaySound( sv_edict_t *ed, float volume, const char *sample ); +void SV_PlaySound( sv_edict_t *ed, float volume, float pitch, const char *sample ); bool SV_movestep( edict_t *ent, vec3_t move, bool relink, bool noenemy, bool settrace ); // diff --git a/engine/server/sv_edict.h b/engine/server/sv_edict.h index 1ffd9e67..b05fa2dc 100644 --- a/engine/server/sv_edict.h +++ b/engine/server/sv_edict.h @@ -37,7 +37,6 @@ struct sv_globalvars_s float trace_hitgroup; float trace_flags; int trace_ent; - func_t CreateAPI; func_t StartFrame; func_t EndFrame; func_t PlayerPreThink; @@ -47,6 +46,7 @@ struct sv_globalvars_s func_t PutClientInServer; func_t ClientCommand; func_t ClientUserInfoChanged; + func_t EmitSound; }; struct sv_entvars_s @@ -152,6 +152,6 @@ struct sv_entvars_s float team; }; -#define PROG_CRC_SERVER 3519 +#define PROG_CRC_SERVER 1737 #endif//SV_EDICT_H \ No newline at end of file diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 63019062..b2d1608a 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -29,6 +29,7 @@ cvar_t *sv_maxspeed; cvar_t *sv_accelerate; cvar_t *sv_friction; cvar_t *sv_newprotocol; +cvar_t *sv_physics; cvar_t *hostname; cvar_t *public_server; // should heartbeats be sent @@ -371,6 +372,7 @@ void SV_Init( void ) sv_accelerate = Cvar_Get( "sv_accelerate", "10", 0, "rate at which a player accelerates to sv_maxspeed" ); sv_friction = Cvar_Get( "sv_friction", "4", 0, "how fast you slow down" ); sv_newprotocol = Cvar_Get( "sv_protocol", "0", CVAR_LATCH|CVAR_ARCHIVE, "using protocol version 0 or 1" ); + sv_physics = Cvar_Get( "cm_physic", "1", CVAR_ARCHIVE|CVAR_LATCH, "change physic model: 0 - Classic Quake Physic, 1 - Physics Engine" ); public_server = Cvar_Get ("public", "0", 0, "change server type from private to public" ); diff --git a/engine/server/sv_move.c b/engine/server/sv_move.c index 25a2d643..181fda3b 100644 --- a/engine/server/sv_move.c +++ b/engine/server/sv_move.c @@ -483,13 +483,15 @@ void SV_PlayerMove( sv_edict_t *ed ) VectorCopy(pm.ps.viewangles, player->priv.sv->s.viewangles ); } -void SV_PlaySound( sv_edict_t *ed, float volume, const char *sample ) +void SV_PlaySound( sv_edict_t *ed, float volume, float pitch, const char *sample ) { - float vol = bound( 0.0f, volume/255.0f, 255.0f ); - int sound_idx = SV_SoundIndex( sample ); - edict_t *ent; if( !ed ) ed = prog->edicts->priv.sv; - ent = PRVM_PROG_TO_EDICT( ed->serialnumber ); - //SV_StartSound( ent->progs.sv->origin, ent, CHAN_BODY, sound_idx, vol, 1.0f, 0 ); + PRVM_G_INT(OFS_PARM0) = ed->serialnumber; + PRVM_G_FLOAT(OFS_PARM1) = CHAN_AUTO; + PRVM_G_INT(OFS_PARM2) = PRVM_SetEngineString( sample ); + PRVM_G_FLOAT(OFS_PARM3) = volume; + PRVM_G_FLOAT(OFS_PARM4) = ATTN_NORM; + PRVM_G_FLOAT(OFS_PARM5) = bound( 1, pitch * PITCH_NORM, 255 ); + PRVM_ExecuteProgram( prog->globals.sv->EmitSound, "EmitSound" ); } \ No newline at end of file diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index cee12ba6..0fa41757 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -1706,19 +1706,23 @@ void SV_Physics_ClientMove( sv_client_t *client, usercmd_t *cmd ) PRVM_ExecuteProgram( prog->globals.sv->PlayerPreThink, "PlayerPreThink" ); prog->globals.sv->frametime = sv.frametime; - // make sure the velocity is sane (not a NaN) - SV_CheckVelocity( ent ); - if(DotProduct(ent->progs.sv->velocity, ent->progs.sv->velocity) < 0.0001) - VectorClear( ent->progs.sv->velocity ); + if( !sv_physics->integer ) + { + // make sure the velocity is sane (not a NaN) + SV_CheckVelocity( ent ); + if( DotProduct(ent->progs.sv->velocity, ent->progs.sv->velocity) < 0.0001) + VectorClear( ent->progs.sv->velocity ); - // perform MOVETYPE_WALK behavior - if(!SV_CheckWater (ent) && !((int)ent->progs.sv->aiflags & AI_WATERJUMP)) - SV_AddGravity( ent ); - SV_CheckStuck( ent ); - SV_WalkMove( ent ); - SV_CheckVelocity( ent ); - SV_LinkEdict( ent ); - SV_CheckVelocity( ent ); + // perform MOVETYPE_WALK behavior + if(!SV_CheckWater (ent) && !((int)ent->progs.sv->aiflags & AI_WATERJUMP)) + SV_AddGravity( ent ); + SV_CheckStuck( ent ); + SV_WalkMove( ent ); + SV_CheckVelocity( ent ); + SV_LinkEdict( ent ); + SV_CheckVelocity( ent ); + } + else SV_LinkEdict( ent ); if( ent->progs.sv->movetype != MOVETYPE_NOCLIP ) SV_TouchTriggers( ent ); diff --git a/engine/server/sv_progs.c b/engine/server/sv_progs.c index 14876e34..be7a6bce 100644 --- a/engine/server/sv_progs.c +++ b/engine/server/sv_progs.c @@ -167,7 +167,7 @@ void SV_SetModel (edict_t *ent, const char *name) if( mod ) SV_SetMinMaxSize( ent, mod->mins, mod->maxs, false ); // FIXME: translate angles correctly - angles[0] = ent->progs.sv->angles[0] + 90; + angles[0] = ent->progs.sv->angles[0] - 180; angles[1] = ent->progs.sv->angles[1]; angles[2] = ent->progs.sv->angles[2] - 90; @@ -675,6 +675,13 @@ void SV_RestoreEdict( edict_t *ent ) ent->priv.sv->s.soundindex = SV_SoundIndex(PRVM_GetString(ent->progs.sv->loopsound)); } +bool SV_ParseKeyValue( edict_t *ent, const char *key, const char *value ) +{ + // FIXME: implement + Msg("ParseKeyValue: %s - %s\n", key, value ); + return false; +} + void SV_VM_Begin( void ) { PRVM_Begin; @@ -2357,6 +2364,20 @@ void PF_setsky( void ) SV_ConfigString( CS_SKYNAME, PRVM_G_STRING(OFS_PARM0)); } +/* +=============== +PF_music + +void music( string trackname ) +=============== +*/ +void PF_music( void ) +{ + if(!VM_ValidateArgs( "music", 1 )) + return; + SV_ConfigString( CS_BACKGROUND_TRACK, PRVM_G_STRING(OFS_PARM0)); +} + /* ============== PF_dropclient @@ -2509,7 +2530,7 @@ NULL, // #126 isEntOnFloor PF_droptofloor, // #127 float droptofloor( void ) PF_walkmove, // #128 float walkmove(float yaw, float dist) PF_setorigin, // #129 void setorigin(entity e, vector o) -NULL, // #130 -- reserved -- +PF_music, // #130 void music( string trackname ) NULL, // #131 -- reserved -- PF_traceline, // #132 void traceline(vector v1, vector v2, float mask, entity ignore) PF_tracetoss, // #133 void tracetoss (entity e, entity ignore) @@ -2636,6 +2657,7 @@ void SV_InitServerProgs( void ) prog->free_edict = SV_FreeEdict; prog->count_edicts = SV_CountEdicts; prog->load_edict = SV_LoadEdict; + prog->keyvalue_edict = SV_ParseKeyValue; prog->restore_edict = SV_RestoreEdict; prog->filecrc = PROG_CRC_SERVER; diff --git a/physic/cm_callback.c b/physic/cm_callback.c index 0cdcb64f..1929ad6e 100644 --- a/physic/cm_callback.c +++ b/physic/cm_callback.c @@ -61,7 +61,7 @@ void Callback_ContactEnd( const NewtonMaterial* material ) { float pitch = cms.touch_info.normal_speed - 15.0f; // TODO: play impact sound here - pi.PlaySound( edict, pitch, "materials/metal/bustmetal1.wav" ); + pi.PlaySound( edict, 0.95f, pitch, "plats/train2.wav" ); // FIXME: get sound from material desc } // if the max contact speed is larger than some minimum value. play a sound @@ -69,7 +69,7 @@ void Callback_ContactEnd( const NewtonMaterial* material ) { float pitch = cms.touch_info.normal_speed - 5.0f; // TODO: play scratch sound here - pi.PlaySound( edict, pitch, "materials/metal/pushmetal1.wav" ); + pi.PlaySound( edict, 0.95f, pitch, "misc/swing1.wav" ); // FIXME: get sound from material desc } } diff --git a/public/physic_api.h b/public/physic_api.h index 851b9c25..63728428 100644 --- a/public/physic_api.h +++ b/public/physic_api.h @@ -120,7 +120,7 @@ typedef struct physic_imp_s void (*ClientMove)( sv_edict_t *ed ); void (*Transform)( sv_edict_t *ed, const vec3_t org, const matrix3x3 matrix ); - void (*PlaySound)( sv_edict_t *ed, float volume, const char *sample ); + void (*PlaySound)( sv_edict_t *ed, float volume, float pitch, const char *sample ); float *(*GetModelVerts)( sv_edict_t *ent, int *numvertices ); } physic_imp_t; diff --git a/public/vprogs_api.h b/public/vprogs_api.h index a97fb9c6..fa395254 100644 --- a/public/vprogs_api.h +++ b/public/vprogs_api.h @@ -159,6 +159,7 @@ typedef struct prvm_prog_s void (*count_edicts)(void); bool (*load_edict)(edict_t *ent); // initialize edict for first loading void (*restore_edict)(edict_t *ent); // restore edict from savegame or changelevel + bool (*keyvalue_edict)(edict_t *ent, const char *key, const char *value ); // KeyValueData void (*init_cmd)(void); void (*reset_cmd)(void); void (*error_cmd)(const char *format, ...); diff --git a/public/vsound_api.h b/public/vsound_api.h index a8292ceb..aeb201d1 100644 --- a/public/vsound_api.h +++ b/public/vsound_api.h @@ -28,6 +28,11 @@ typedef enum ATTN_IDLE, ATTN_STATIC, // diminish very rapidly with distance } snd_attenuation_t; + +#define PITCH_LOW 95 // other values are possible - 0-255, where 255 is very high +#define PITCH_NORM 100 // non-pitch shifted +#define PITCH_HIGH 120 + /* ============================================================================== @@ -47,7 +52,7 @@ typedef struct vsound_exp_s sound_t (*RegisterSound)( const char *name ); void (*EndRegistration)( void ); - void (*StartSound)( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, bool loop ); + void (*StartSound)( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, float pitch, bool loop ); 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 ); diff --git a/release.bat b/release.bat index 4c8e91ee..0139a6e4 100644 --- a/release.bat +++ b/release.bat @@ -67,5 +67,5 @@ 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 -game tmpQuArK -dev 3 -log +map phystest +quake.exe -game tmpQuArK -dev 3 -log +map qctest :done \ No newline at end of file diff --git a/todo.log b/todo.log index 9c7cfb95..a5f9ba68 100644 --- a/todo.log +++ b/todo.log @@ -19,7 +19,7 @@ fopen Beta 13.12.08 0. move effects to client.dat OK -1. fixangle +1. Xash 0.45 ents 0. light_environment 1. научить оружие стрелять diff --git a/vprogs/pr_comp.c b/vprogs/pr_comp.c index 590203cb..30c6a949 100644 --- a/vprogs/pr_comp.c +++ b/vprogs/pr_comp.c @@ -165,6 +165,8 @@ opcode_t pr_opcodes[] = {"!", "NOT_S", -1, ASSOC_LEFT, &type_string, &type_void, &type_float}, {"!", "NOT_ENT", -1, ASSOC_LEFT, &type_entity, &type_void, &type_float}, {"!", "NOT_FNC", -1, ASSOC_LEFT, &type_function, &type_void, &type_float}, +{"~", "NOT_BITI", -1, ASSOC_LEFT, &type_integer, &type_void, &type_integer}, +{"~", "NOT_BITF", -1, ASSOC_LEFT, &type_float, &type_void, &type_float}, {"", "IF", -1, ASSOC_RIGHT,&type_float, NULL, &type_void}, {"", "IFNOT", -1, ASSOC_RIGHT,&type_float, NULL, &type_void}, {"", "CALL0", -1, ASSOC_LEFT, &type_function, &type_void, &type_void}, @@ -207,8 +209,8 @@ opcode_t pr_opcodes[] = {"", "THINKTIME", -1, ASSOC_LEFT, &type_entity, &type_float, &type_void}, {"|=", "BITSET_F", 6, ASSOC_RIGHT,&type_float, &type_float, &type_float}, {"|=", "BITSETP_F", 6, ASSOC_RIGHT,&type_pointer, &type_float, &type_float}, -{"(-)", "BITCLR_F", 6, ASSOC_RIGHT,&type_float, &type_float, &type_float}, -{"(-)", "BITCLRP_F", 6, ASSOC_RIGHT,&type_pointer, &type_float, &type_float}, +{"&=", "BITCLR_F", 6, ASSOC_RIGHT,&type_float, &type_float, &type_float}, +{"&=", "BITCLRP_F", 6, ASSOC_RIGHT,&type_pointer, &type_float, &type_float}, {"", "RAND0", -1, ASSOC_LEFT, &type_void, &type_void, &type_float}, {"", "RAND1", -1, ASSOC_LEFT, &type_float, &type_void, &type_float}, {"", "RAND2", -1, ASSOC_LEFT, &type_float, &type_float, &type_float}, @@ -252,6 +254,10 @@ opcode_t pr_opcodes[] = {"^", "POWER_I", 3, ASSOC_LEFT, &type_integer, &type_integer, &type_integer}, {">>", "RSHIFT_I", 3, ASSOC_LEFT, &type_integer, &type_integer, &type_integer}, {"<<", "LSHIFT_I", 3, ASSOC_LEFT, &type_integer, &type_integer, &type_integer}, +{">>", "RSHIFT_F", 3, ASSOC_LEFT, &type_float, &type_float, &type_float}, +{"<<", "LSHIFT_F", 3, ASSOC_LEFT, &type_float, &type_float, &type_float}, +{"%", "OP_MODULO_I", 3, ASSOC_LEFT, &type_integer, &type_integer, &type_integer}, +{"%", "OP_MODULO_F", 3, ASSOC_LEFT, &type_float, &type_float, &type_float}, {"", "GET_POINTER", -1, ASSOC_LEFT, &type_float, &type_integer, &type_pointer}, {"", "ARRAY_OFS", -1, ASSOC_LEFT, &type_pointer, &type_integer, &type_pointer}, {"=", "LOADA_F", 6, ASSOC_LEFT, &type_float, &type_integer, &type_float}, @@ -325,6 +331,7 @@ opcode_t pr_opcodes[] = {"=", "STOREP_P", 6, ASSOC_RIGHT,&type_pointer, &type_pointer, &type_void}, {"", "PUSH", -1, ASSOC_RIGHT,&type_float, &type_void, &type_pointer}, {"", "POP", -1, ASSOC_RIGHT,&type_float, &type_void, &type_void}, +{"", "POP", -1, ASSOC_RIGHT,&type_float, &type_void, &type_void}, {"|=", "BITSET_I", 6, ASSOC_RIGHT,&type_integer, &type_integer, &type_integer}, {"|=", "BITSETP_I", 6, ASSOC_RIGHT,&type_pointer, &type_integer, &type_integer}, {"*=", "MULSTORE_I", 6, ASSOC_RIGHT,&type_integer, &type_integer, &type_integer}, @@ -344,7 +351,7 @@ keyword_t pr_keywords[] = {KEYWORD_IF, "if", "", 0 }, {KEYWORD_VOID, "void", "", 0 }, {KEYWORD_ELSE, "else", "", 0 }, -{KEYWORD_LOCAL, "local", "", 0 }, +{KEYWORD_LOCAL, "local", "", 0 }, // FIXME: get rid of this {KEYWORD_WHILE, "while", "", 0 }, {KEYWORD_ENTITY, "entity", "", 0 }, {KEYWORD_FLOAT, "float", "", 0 }, @@ -367,13 +374,13 @@ keyword_t pr_keywords[] = {KEYWORD_SWITCH, "switch", "", 0 }, {KEYWORD_TYPEDEF, "typedef", "", 0 }, {KEYWORD_EXTERN, "extern", "", 0 }, -{KEYWORD_VAR, "var", "", 0 }, +{KEYWORD_VAR, "var", "", 0 }, // FIXME: get rid of this {KEYWORD_UNION, "union", "", 0 }, {KEYWORD_THINKTIME, "thinktime", "", 0 }, {KEYWORD_BOOL, "bool", "BOOL", 0 }, {KEYWORD_ASM, "asm", "_asm", 0 }, -{KEYWORD_SHARED, "shared", "_export",0 }, // multiprogs stuff -{KEYWORD_NOSAVE, "nosave", "", 0 }, +{KEYWORD_SHARED, "shared", "_export",0 }, // rename to ? +{KEYWORD_NOSAVE, "nosave", "", 0 }, // rename to ? {NUM_KEYWORDS, "", "", 0 }, }; @@ -418,6 +425,10 @@ opcode_t *opcodeprioritized[TOP_PRIORITY+1][64] = &pr_opcodes[OP_POWER_I], &pr_opcodes[OP_RSHIFT_I], &pr_opcodes[OP_LSHIFT_I], + &pr_opcodes[OP_RSHIFT_F], + &pr_opcodes[OP_LSHIFT_F], + &pr_opcodes[OP_MODULO_I], + &pr_opcodes[OP_MODULO_F], NULL }, { @@ -2544,9 +2555,9 @@ def_t *PR_Term( void ) def_t *e, *e2; etype_t t; - if (pr_token_type == tt_punct) // a little extra speed... + if( pr_token_type == tt_punct ) // a little extra speed... { - if (PR_CheckToken("++")) + if( PR_CheckToken( "++" )) { qcc_usefulstatement = true; e = PR_Term (); @@ -2567,7 +2578,7 @@ def_t *PR_Term( void ) } return e; } - else if (PR_CheckToken("--")) + else if( PR_CheckToken( "--" )) { qcc_usefulstatement = true; e = PR_Term (); @@ -2587,7 +2598,7 @@ def_t *PR_Term( void ) } return e; } - if (PR_CheckToken ("!")) + if( PR_CheckToken( "!" )) { e = PR_Expression (NOT_PRIORITY, false); t = e->type->type; @@ -2621,7 +2632,26 @@ def_t *PR_Term( void ) } return e2; } - else if (PR_CheckToken ("&")) + else if( PR_CheckToken( "~" )) + { + e = PR_Expression( NOT_PRIORITY, false ); + t = e->type->type; + switch( t ) + { + case ev_float: + e2 = PR_Statement( &pr_opcodes[OP_NOT_BITF], e, 0, NULL ); + break; + case ev_integer: + e2 = PR_Statement( &pr_opcodes[OP_NOT_BITI], e, 0, NULL ); + break; // functions are integer values too. + default: + e2 = NULL; // shut up compiler warning; + PR_ParseError( ERR_BADNOTTYPE, "type mismatch for ~" ); + break; + } + return e2; + } + else if( PR_CheckToken( "&" )) { int st = numstatements; e = PR_Expression (NOT_PRIORITY, false); diff --git a/vprogs/pr_edict.c b/vprogs/pr_edict.c index 5b3126fc..83ba0d81 100644 --- a/vprogs/pr_edict.c +++ b/vprogs/pr_edict.c @@ -691,9 +691,11 @@ void PRVM_ED_Read( int s_table, int entnum, dkeyvalue_t *fields, int numpairs ) key = PRVM_ED_FindField( keyname ); if( !key ) { - MsgDev( D_WARN, "%s: unknown field '%s'\n", PRVM_NAME, keyname); + PRVM_GCALL(keyvalue_edict)(ent, keyname, value ); + else MsgDev( D_WARN, "%s: unknown field '%s'\n", PRVM_NAME, keyname); continue; } + // simple huh ? if(!PRVM_ED_ParseEpair( ent, key, value )) PRVM_ERROR( "PRVM_ED_ParseEdict: parse error" ); } diff --git a/vprogs/pr_exec.c b/vprogs/pr_exec.c index 45663b8b..b052b163 100644 --- a/vprogs/pr_exec.c +++ b/vprogs/pr_exec.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "vprogs.h" +#include "mathlib.h" char *prvm_opnames[] = { @@ -84,6 +85,8 @@ char *prvm_opnames[] = "^2NOT_S", "^2NOT_ENT", "^2NOT_FNC", +"^2NOT_BITI", +"^2NOT_BITF", "^5IF", "^5IFNOT", @@ -696,6 +699,12 @@ chooseexecprogram: case OP_NOT_ENT: OPC->_float = (OPA->edict == 0); break; + case OP_NOT_BITI: + OPC->_int = ~OPA->_int; + break; + case OP_NOT_BITF: + OPC->_float = (float)(~(int)OPA->_float); + break; case OP_EQ_F: OPC->_float = (float)(OPA->_float == OPB->_float); break; @@ -709,20 +718,20 @@ chooseexecprogram: OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]); break; case OP_EQ_S: - if (OPA->string == OPB->string) OPC->_float = true; // try fast method first - else if (!OPA->string) + if( OPA->string == OPB->string ) OPC->_float = true; // try fast method first + else if( !OPA->string ) { - if (!OPB->string || !*PRVM_GetString(OPB->string)) + if( !OPB->string || !*PRVM_GetString( OPB->string )) OPC->_float = true; else OPC->_float = false; } - else if (!OPB->string) + else if( !OPB->string ) { - if (!OPA->string || !*PRVM_GetString(OPA->string)) + if( !OPA->string || !*PRVM_GetString( OPA->string )) OPC->_float = true; else OPC->_float = false; } - else OPC->_float = !com.strcmp(PRVM_GetString(OPA->string), PRVM_GetString(OPB->string)); + else OPC->_float = !com.strcmp( PRVM_GetString( OPA->string ), PRVM_GetString( OPB->string )); break; case OP_EQ_E: OPC->_float = (float)(OPA->_int == OPB->_int); @@ -1139,6 +1148,12 @@ chooseexecprogram: case OP_LSHIFT_I: OPC->_int = OPA->_int << OPB->_int; break; + case OP_RSHIFT_F: + OPC->_float = (float)((int)OPA->_float >> (int)OPB->_float); + break; + case OP_LSHIFT_F: + OPC->_float = (float)((int)OPA->_float << (int)OPB->_float); + break; case OP_FETCH_GBL_F: case OP_FETCH_GBL_S: case OP_FETCH_GBL_E: @@ -1176,11 +1191,11 @@ chooseexecprogram: ptr->_float = (float)((int)ptr->_float | (int)OPA->_float); break; case OP_BITCLR: - OPB->_float = (float)((int)OPB->_float & ~((int)OPA->_float)); + OPB->_float = (float)((int)OPB->_float & ((int)OPA->_float)); break; case OP_BITCLRP: ptr = PRVM_ED_POINTER(OPB); - ptr->_float = (float)((int)ptr->_float & ~((int)OPA->_float)); + ptr->_float = (float)((int)ptr->_float & ((int)OPA->_float)); break; case OP_SWITCH_F: case OP_SWITCH_V: @@ -1428,6 +1443,11 @@ chooseexecprogram: PRVM_ERROR("OP_STATE not supported by %s", PRVM_NAME); } break; + case OP_MODULO_I: + OPC->_int = (OPA->_int % OPB->_int); + case OP_MODULO_F: + OPC->_float = fmod( OPA->_float, OPB->_float ); + break; default: vm.prog->xfunction->profile += (st - startst); vm.prog->xstatement = st - vm.prog->statements; diff --git a/vprogs/pr_lex.c b/vprogs/pr_lex.c index 9a307269..1d509593 100644 --- a/vprogs/pr_lex.c +++ b/vprogs/pr_lex.c @@ -30,8 +30,8 @@ bool recursivefunctiontype; #define GoToEndLine() while(*pr_file_p != '\n' && *pr_file_p != '\0'){ pr_file_p++; } // longer symbols must be before a shorter partial match -char *pr_punctuation1[] = {"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "(+)", "|=", "(-)", "++", "--", "->", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "#" , "@", "&" , "|", "^", ":", NULL}; -char *pr_punctuation2[] = {"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "|=", "|=", "(-)", "++", "--", ".", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "#" , "@", "&" , "|", "^", ":", NULL}; +char *pr_punctuation1[] = {"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "(+)", "|=", "(-)", "&=", "++", "--", "->", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "#" , "%", "@", "&" , "|", "^", "~", ":", NULL}; +char *pr_punctuation2[] = {"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "|=", "|=", "&=", "&=", "++", "--", ".", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "<<", "<", ">>", ">" , "#" , "%", "@", "&" , "|", "^", "~", ":", NULL}; optimisations_t pr_optimisations[] = { @@ -1020,12 +1020,12 @@ void PR_LexString (void) if (*end == '-') break; if (*end == '*') break; if (*end == '/') break; + if (*end == '%') break; if (*end =='\\') break; if (*end == '|') break; if (*end == '&') break; if (*end == '=') break; if (*end == '^') break; - if (*end == '~') break; if (*end == '[') break; if (*end == ']') break; if (*end =='\"') break; @@ -1290,27 +1290,26 @@ void PR_LexName (void) PR_LexPunctuation ============== */ -void PR_LexPunctuation (void) +void PR_LexPunctuation( void ) { - int i; - int len; + int i, len; char *p; pr_token_type = tt_punct; - for (i = 0; (p = pr_punctuation1[i]) != NULL; i++) + for( i = 0; (p = pr_punctuation1[i]) != NULL; i++ ) { - len = com.strlen(p); - if (!com.strncmp(p, pr_file_p, len) ) + len = com.strlen( p ); + if(!com.strncmp( p, pr_file_p, len )) { - com.strcpy (pr_token, pr_punctuation2[i]); - if (p[0] == '{') pr_bracelevel++; - else if (p[0] == '}') pr_bracelevel--; + com.strcpy( pr_token, pr_punctuation2[i] ); + if( p[0] == '{' ) pr_bracelevel++; + else if( p[0] == '}' ) pr_bracelevel--; pr_file_p += len; return; } } - PR_ParseError (ERR_UNKNOWNPUCTUATION, "Unknown punctuation"); + PR_ParseError( ERR_UNKNOWNPUCTUATION, "Unknown punctuation" ); } /* @@ -1818,11 +1817,11 @@ int PR_CheakCompConst( void ) if (*end == '-') break; if (*end == '*') break; if (*end == '/') break; + if (*end == '%') break; if (*end == '|') break; if (*end == '&') break; if (*end == '=') break; if (*end == '^') break; - if (*end == '~') break; if (*end == '[') break; if (*end == ']') break; if (*end =='\"') break; @@ -2060,22 +2059,22 @@ Advanced version of Com_ParseToken() Sets pr_token, pr_token_type, and possibly pr_immediate and pr_immediate_type ============== */ -void PR_Lex (void) +void PR_Lex( void ) { int c; pr_token[0] = 0; - if (!pr_file_p) goto end_of_file; + if( !pr_file_p ) goto end_of_file; PR_LexWhitespace(); - if (!pr_file_p) goto end_of_file; + if( !pr_file_p ) goto end_of_file; c = *pr_file_p; - if (!c) goto end_of_file; + if( !c ) goto end_of_file; // handle quoted strings as a unit - if (c == '\"') + if( c == '\"' ) { PR_LexString (); return; @@ -2088,24 +2087,13 @@ void PR_Lex (void) return; } - // if the first character is a valid identifier, parse until a non-id - // character is reached - if ( c == '~' || c == '%') - { - // let's see which one we make into an operator first... possibly both... - pr_file_p++; - pr_token_type = tt_immediate; - pr_immediate_type = type_integer; - pr_immediate._int = PR_LexInteger (); - return; - } - if ( c == '0' && pr_file_p[1] == 'x') + if( c == '0' && pr_file_p[1] == 'x' ) { pr_token_type = tt_immediate; PR_LexNumber(); return; } - if ( (c == '.'&&pr_file_p[1] >='0' && pr_file_p[1] <= '9') || (c >= '0' && c <= '9') || ( c=='-' && pr_file_p[1]>='0' && pr_file_p[1] <='9') ) + if(( c == '.'&&pr_file_p[1] >='0' && pr_file_p[1] <= '9') || (c >= '0' && c <= '9') || ( c=='-' && pr_file_p[1]>='0' && pr_file_p[1] <='9') ) { pr_token_type = tt_immediate; pr_immediate_type = type_float; @@ -2362,19 +2350,19 @@ PR_ParseName Checks to see if the current token is a valid name ============ */ -char *PR_ParseName (void) +char *PR_ParseName( void ) { static char ident[MAX_NAME]; char *ret; - if (pr_token_type != tt_name) PR_ParseError (ERR_NOTANAME, "\"%s\" - not a name", pr_token); - if (com.strlen(pr_token) >= MAX_NAME-1) PR_ParseError (ERR_NAMETOOLONG, "name too long"); + if( pr_token_type != tt_name ) PR_ParseError( ERR_NOTANAME, "\"%s\" - not a name", pr_token ); + if( com.strlen(pr_token ) >= MAX_NAME-1 ) PR_ParseError (ERR_NAMETOOLONG, "name too long" ); - com.strcpy (ident, pr_token); - PR_Lex (); + com.strcpy( ident, pr_token ); + PR_Lex(); - ret = Qalloc(com.strlen(ident) + 1); - com.strcpy(ret, ident); + ret = Qalloc( com.strlen( ident ) + 1 ); + com.strcpy( ret, ident ); return ret; } diff --git a/vprogs/pr_utils.c b/vprogs/pr_utils.c index 14f43ef0..706282ea 100644 --- a/vprogs/pr_utils.c +++ b/vprogs/pr_utils.c @@ -502,7 +502,7 @@ word PR_WriteProgdefs( void ) switch( crc ) { - case 3519: + case 1737: PR_Message("Xash3D unmodified server.dat\n"); if(!com.strcmp(progsoutname, "unknown.dat")) com.strcpy(progsoutname, "server.dat"); break; diff --git a/vprogs/vprogs.h b/vprogs/vprogs.h index 9f5e6afb..89e0aa4b 100644 --- a/vprogs/vprogs.h +++ b/vprogs/vprogs.h @@ -84,6 +84,8 @@ enum op_state OP_NOT_S, OP_NOT_ENT, OP_NOT_FNC, + OP_NOT_BITI, + OP_NOT_BITF, OP_IF, OP_IFNOT, // 50 OP_CALL0, @@ -104,7 +106,6 @@ enum op_state OP_BITAND, // = (float) & (float); // of cource converting into integer in real code OP_BITOR, - // version 7 started OP_MULSTORE_F, // f *= f OP_MULSTORE_V, // v *= f OP_MULSTOREP_F, // e.f *= f @@ -194,6 +195,10 @@ enum op_state OP_POWER_I, OP_RSHIFT_I, OP_LSHIFT_I, + OP_RSHIFT_F, + OP_LSHIFT_F, + OP_MODULO_I, // (int)c = (int)a % (int)b + OP_MODULO_F, // (float)c = fmod( (float)a, (float)b ) OP_GLOBAL_ADD, OP_POINTER_ADD, // pointer to 32 bit (remember to *3 for vectors) @@ -280,7 +285,6 @@ enum op_state OP_PUSH, OP_POP, - // version 8 started OP_NUMOPS, }; diff --git a/vsound/s_main.c b/vsound/s_main.c index 270de59d..8b0ffafd 100644 --- a/vsound/s_main.c +++ b/vsound/s_main.c @@ -204,6 +204,7 @@ static void S_SpatializeChannel( channel_t *ch ) // update volume and rolloff factor palSourcef( ch->sourceNum, AL_GAIN, ch->volume ); + palSourcef( ch->sourceNum, AL_PITCH, ch->pitch ); palSourcef( ch->sourceNum, AL_ROLLOFF_FACTOR, s_rolloffFactor->value ); } @@ -315,8 +316,7 @@ bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn ) 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 ); + MsgDev( D_ERROR, "dropped sound \"sound/%s\"\n", sfx->name ); return false; } @@ -324,7 +324,8 @@ bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn ) ch->loopnum = entnum; ch->loopframe = al_state.framecount; ch->fixedPosition = false; - ch->volume = 1.0; + ch->volume = 1.0f; + ch->pitch = 1.0f; ch->distanceMult = 1.0f / ATTN_STATIC; S_SpatializeChannel( ch ); @@ -409,6 +410,7 @@ static void S_IssuePlaySounds( void ) ch->fixedPosition = ps->fixedPosition; VectorCopy( ps->position, ch->position ); ch->volume = ps->volume; + ch->pitch = ps->pitch; if( ps->attenuation != ATTN_NONE ) ch->distanceMult = 1.0 / ps->attenuation; else ch->distanceMult = 0.0; @@ -430,7 +432,7 @@ if origin is NULL, the sound will be dynamically sourced from the entity. entchannel 0 will never override a playing sound. ================= */ -void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, float vol, float attn, bool use_loop ) +void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, float vol, float attn, float pitch, bool use_loop ) { playSound_t *ps, *sort; sfx_t *sfx = NULL; @@ -465,10 +467,11 @@ void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t handle, fl else ps->fixedPosition = false; ps->volume = vol; + ps->pitch = pitch / PITCH_NORM; ps->attenuation = attn; ps->beginTime = Sys_DoubleTime(); - // Sort into the pending playSounds list + // sort into the pending playSounds list for( sort = s_pendingPlaySounds.next; sort != &s_pendingPlaySounds && sort->beginTime < ps->beginTime; sort = sort->next ); ps->next = sort; @@ -492,7 +495,7 @@ bool S_StartLocalSound( const char *name ) return false; sfxHandle = S_RegisterSound( name ); - S_StartSound( NULL, al_state.clientnum, CHAN_AUTO, sfxHandle, 1.0f, ATTN_NONE, false ); + S_StartSound( NULL, al_state.clientnum, CHAN_AUTO, sfxHandle, 1.0f, ATTN_NONE, PITCH_NORM, false ); return true; } diff --git a/vsound/sound.h b/vsound/sound.h index c7aa6fd9..67658d4c 100644 --- a/vsound/sound.h +++ b/vsound/sound.h @@ -86,6 +86,7 @@ typedef struct playsound_s float volume; float attenuation; float beginTime; // Begin at this time + float pitch; } playSound_t; typedef struct @@ -105,6 +106,7 @@ typedef struct bool fixedPosition; // use position instead of fetching entity's origin vec3_t position; // only use if fixedPosition is set float volume; + float pitch; float distanceMult; uint sourceNum; // openAL source } channel_t; @@ -167,7 +169,7 @@ void S_Shutdown( void ); void S_Activate( bool active ); void S_SoundList_f( void ); void S_CheckForErrors( void ); -void S_StartSound( const vec3_t pos, int entnum, int channel, sound_t sfx, float vol, float attn, bool use_loop ); +void S_StartSound(const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, float pitch, bool use_loop); void S_Update( int clientnum, const vec3_t pos, const vec3_t vel, const vec3_t at, const vec3_t up ); void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data ); bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn );