04 Jun 2008
This commit is contained in:
parent
a5b7ffbf24
commit
11da3ddb7d
|
@ -129,7 +129,7 @@ static void ParseShaderFile( char *filename )
|
|||
if ( !Com_GetToken( true )) break;
|
||||
|
||||
si = AllocShaderInfo();
|
||||
strcpy( si->name, com_token );
|
||||
com.strcpy( si->name, com_token );
|
||||
Com_GetToken( true );
|
||||
|
||||
if(!Com_MatchToken( "{" ))
|
||||
|
|
|
@ -671,7 +671,7 @@ bool CG_ParseArgs( int num_argc )
|
|||
{
|
||||
cls.cg_argc = 0;
|
||||
memset(cls.cg_argv, 0, MAX_PARMS * MAX_QPATH );
|
||||
strncpy( cls.cg_builtin, com_token, MAX_QPATH );
|
||||
com.strncpy( cls.cg_builtin, com_token, MAX_QPATH );
|
||||
|
||||
// bound range silently
|
||||
num_argc = bound(0, num_argc, MAX_PARMS - 1);
|
||||
|
@ -688,7 +688,7 @@ bool CG_ParseArgs( int num_argc )
|
|||
else if(Com_MatchToken(",")) cls.cg_argc++; // new argument
|
||||
else if(Com_MatchToken("(") || Com_MatchToken(")"))
|
||||
continue; // skip punctuation
|
||||
else strncpy(cls.cg_argv[cls.cg_argc], com_token, MAX_QPATH ); // fill stack
|
||||
else com.strncpy(cls.cg_argv[cls.cg_argc], com_token, MAX_QPATH ); // fill stack
|
||||
}
|
||||
|
||||
if(num_argc > 0 && cls.cg_argc < num_argc - 1)
|
||||
|
@ -958,7 +958,7 @@ void CG_ExecuteProgram( char *section )
|
|||
bool skip = true;
|
||||
|
||||
Com_ResetScript();
|
||||
strncpy( cls.cg_function, section, MAX_QPATH );
|
||||
com.strncpy( cls.cg_function, section, MAX_QPATH );
|
||||
cls.cg_depth = 0;
|
||||
|
||||
// not loaded
|
||||
|
|
|
@ -160,14 +160,17 @@ CL_Pause_f
|
|||
*/
|
||||
void CL_Pause_f (void)
|
||||
{
|
||||
if(!Host_ServerState() && !cls.demoplayback )
|
||||
return; // but allow pause in demos
|
||||
|
||||
// never pause in multiplayer
|
||||
if (Cvar_VariableValue ("maxclients") > 1 || !Host_ServerState ())
|
||||
if( Cvar_VariableValue ("maxclients") > 1 )
|
||||
{
|
||||
Cvar_SetValue ("paused", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
Cvar_SetValue ("paused", !cl_paused->value);
|
||||
Cvar_SetValue( "paused", !cl_paused->value );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -767,13 +770,18 @@ void CL_ReadPackets (void)
|
|||
//
|
||||
// check timeout
|
||||
//
|
||||
if (cls.state >= ca_connected && cls.realtime - cls.netchan.last_received > cl_timeout->value)
|
||||
if( cls.state >= ca_connected && !cls.demoplayback )
|
||||
{
|
||||
if (++cl.timeoutcount > 5) // timeoutcount saves debugger
|
||||
if( cls.realtime - cls.netchan.last_received > cl_timeout->value)
|
||||
{
|
||||
Msg ("\nServer connection timed out.\n");
|
||||
CL_Disconnect ();
|
||||
return;
|
||||
cl.timeoutcount++; // timeoutcount saves debugger
|
||||
|
||||
if( cl.timeoutcount > 5 )
|
||||
{
|
||||
Msg ("\nServer connection timed out.\n");
|
||||
CL_Disconnect ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else cl.timeoutcount = 0;
|
||||
|
@ -857,20 +865,13 @@ static const char *env_suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
|||
|
||||
void CL_RequestNextDownload (void)
|
||||
{
|
||||
unsigned map_checksum; // for detecting cheater maps
|
||||
char fn[MAX_OSPATH];
|
||||
studiohdr_t *pheader;
|
||||
uint map_checksum; // for detecting cheater maps
|
||||
char fn[MAX_OSPATH];
|
||||
studiohdr_t *pheader;
|
||||
|
||||
if(cls.state != ca_connected)
|
||||
return;
|
||||
|
||||
if( cls.demoplayback )
|
||||
{
|
||||
CL_RegisterSounds();
|
||||
CL_PrepRefresh();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!allow_download->value && precache_check < ENV_CNT)
|
||||
precache_check = ENV_CNT;
|
||||
|
||||
|
@ -1100,17 +1101,6 @@ before allowing the client into the server
|
|||
*/
|
||||
void CL_Precache_f (void)
|
||||
{
|
||||
// Yet another hack to let old demos work
|
||||
// the old precache sequence
|
||||
if(Cmd_Argc() < 2)
|
||||
{
|
||||
uint map_checksum; // for detecting cheater maps
|
||||
pe->BeginRegistration( cl.configstrings[CS_MODELS+1], true, &map_checksum );
|
||||
CL_RegisterSounds();
|
||||
CL_PrepRefresh();
|
||||
return;
|
||||
}
|
||||
|
||||
precache_check = CS_MODELS;
|
||||
precache_spawncount = com.atoi(Cmd_Argv(1));
|
||||
precache_model = 0;
|
||||
|
|
|
@ -284,6 +284,8 @@ void CL_PrepRefresh( void )
|
|||
if (!cl.configstrings[CS_MODELS+1][0])
|
||||
return; // no map loaded
|
||||
|
||||
Msg("CL_PrepRefresh: %s\n", cl.configstrings[CS_NAME] );
|
||||
|
||||
// get splash name
|
||||
Cvar_Set( "cl_levelshot_name", va("background/%s.tga", cl.configstrings[CS_NAME]));
|
||||
if(!FS_FileExists(va("graphics/%s", Cvar_VariableString("cl_levelshot_name"))))
|
||||
|
|
|
@ -115,6 +115,7 @@ void Host_InitPhysic( void )
|
|||
// phys callback
|
||||
pi.api_size = sizeof(physic_imp_t);
|
||||
pi.Transform = SV_Transform;
|
||||
pi.PlaySound = SV_PlaySound;
|
||||
pi.ClientMove = SV_PlayerMove;
|
||||
pi.GetModelVerts = SV_GetModelVerts;
|
||||
|
||||
|
|
|
@ -329,6 +329,7 @@ bool SV_CreateMeshBuffer( edict_t *in, cmodel_t *out );
|
|||
void SV_SpawnEntities( const char *mapname, const char *entities );
|
||||
void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count);
|
||||
void SV_Transform( sv_edict_t *ed, matrix4x3 transform );
|
||||
void SV_PlaySound( sv_edict_t *ed, float volume, const char *sample );
|
||||
void SV_FreeEdict (edict_t *ed);
|
||||
void SV_InitEdict (edict_t *e);
|
||||
edict_t *SV_Spawn (void);
|
||||
|
|
|
@ -838,4 +838,15 @@ void SV_PlayerMove( sv_edict_t *ed )
|
|||
VectorCopy(pm.mins, player->progs.sv->mins);
|
||||
VectorCopy(pm.maxs, player->progs.sv->maxs);
|
||||
VectorCopy(pm.ps.viewangles, client->ps.viewangles);
|
||||
}
|
||||
|
||||
void SV_PlaySound( sv_edict_t *ed, float volume, 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 );
|
||||
}
|
|
@ -5,6 +5,72 @@
|
|||
|
||||
#include "cm_local.h"
|
||||
|
||||
int Callback_ContactBegin( const NewtonMaterial* material, const NewtonBody* body0, const NewtonBody* body1 )
|
||||
{
|
||||
// save the collision bodies
|
||||
cm.touch_info.m_body0 = (NewtonBody*) body0;
|
||||
cm.touch_info.m_body1 = (NewtonBody*) body1;
|
||||
cm.touch_info.normal_speed = 0.0f;// clear the contact normal speed
|
||||
cm.touch_info.tangent_speed = 0.0f;// clear the contact sliding speed
|
||||
|
||||
// return one the tell Newton the application wants to process this contact
|
||||
return 1;
|
||||
}
|
||||
|
||||
// this callback is called for every contact between the two bodies
|
||||
int Callback_ContactProcess( const NewtonMaterial* material, const NewtonContact* contact )
|
||||
{
|
||||
float speed0, speed1;
|
||||
vec3_t normal;
|
||||
|
||||
// get the maximum normal speed of this impact. this can be used for particles of playing collision sound
|
||||
speed0 = NewtonMaterialGetContactNormalSpeed( material, contact );
|
||||
if( speed0 > cm.touch_info.normal_speed )
|
||||
{
|
||||
// save the position of the contact (for 3d sound of particles effects)
|
||||
cm.touch_info.normal_speed = speed0;
|
||||
NewtonMaterialGetContactPositionAndNormal( material, &cm.touch_info.position[0], &normal[0] );
|
||||
}
|
||||
|
||||
// get the maximum of the two sliding contact speed
|
||||
speed0 = NewtonMaterialGetContactTangentSpeed( material, contact, 0 );
|
||||
speed1 = NewtonMaterialGetContactTangentSpeed( material, contact, 1 );
|
||||
|
||||
if( speed1 > speed0 ) speed0 = speed1;
|
||||
|
||||
// Get the maximum tangent speed of this contact. this can be used for particles(sparks) of playing scratch sounds
|
||||
if( speed0 > cm.touch_info.tangent_speed )
|
||||
{
|
||||
// save the position of the contact (for 3d sound of particles effects)
|
||||
cm.touch_info.tangent_speed = speed0;
|
||||
NewtonMaterialGetContactPositionAndNormal( material, &cm.touch_info.position[0], &normal[0] );
|
||||
}
|
||||
|
||||
// return one to tell Newton we want to accept this contact
|
||||
return 1;
|
||||
}
|
||||
|
||||
// this function is call after all contacts for this pairs is processed
|
||||
void Callback_ContactEnd( const NewtonMaterial* material )
|
||||
{
|
||||
sv_edict_t *edict = (sv_edict_t *)NewtonBodyGetUserData( cm.touch_info.m_body0 );
|
||||
|
||||
// if the max contact speed is larger than some minimum value. play a sound
|
||||
if( cm.touch_info.normal_speed > 15.0f )
|
||||
{
|
||||
float pitch = cm.touch_info.normal_speed - 15.0f;
|
||||
// TODO: play impact sound here
|
||||
pi.PlaySound( edict, pitch, "materials/metal/bustmetal1.wav" );
|
||||
}
|
||||
|
||||
// if the max contact speed is larger than some minimum value. play a sound
|
||||
if( cm.touch_info.normal_speed > 5.0f )
|
||||
{
|
||||
float pitch = cm.touch_info.normal_speed - 5.0f;
|
||||
// TODO: play scratch sound here
|
||||
pi.PlaySound( edict, pitch, "materials/metal/pushmetal1.wav" );
|
||||
}
|
||||
}
|
||||
|
||||
void Callback_ApplyForce( const NewtonBody* body )
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "physic.h"
|
||||
#include "basefiles.h"
|
||||
|
||||
#define MAX_MATERIALS 64
|
||||
#define CAPSULE_MODEL_HANDLE MAX_MODELS - 2
|
||||
#define BOX_MODEL_HANDLE MAX_MODELS - 1
|
||||
|
||||
|
@ -40,6 +41,25 @@ typedef struct
|
|||
int floodvalid;
|
||||
} carea_t;
|
||||
|
||||
typedef struct material_info_s
|
||||
{
|
||||
string name;
|
||||
float softness;
|
||||
float elasticity;
|
||||
float friction_static;
|
||||
float friction_kinetic;
|
||||
|
||||
} material_info_t;
|
||||
|
||||
typedef struct collide_info_s
|
||||
{
|
||||
NewtonBody *m_body0;
|
||||
NewtonBody *m_body1;
|
||||
vec3_t position;
|
||||
float normal_speed;
|
||||
float tangent_speed;
|
||||
} collide_info_t;
|
||||
|
||||
typedef struct clipmap_s
|
||||
{
|
||||
string name;
|
||||
|
@ -99,6 +119,9 @@ typedef struct clipmap_s
|
|||
NewtonBody *body;
|
||||
matrix4x4 matrix; // world matrix
|
||||
NewtonJoint *upVector; // world upvector
|
||||
material_info_t mat[MAX_MATERIALS];
|
||||
uint num_materials; // number of parsed materials
|
||||
collide_info_t touch_info; // global info about two touching objects
|
||||
bool loaded; // map is loaded?
|
||||
bool tree_build; // phys tree is created ?
|
||||
bool use_thread; // bsplib use thread
|
||||
|
@ -204,7 +227,6 @@ extern float m_yawAngle;
|
|||
extern float m_maxTranslation;
|
||||
extern vec3_t m_size;
|
||||
extern vec3_t m_stepContact;
|
||||
extern vec3_t m_forceVector;
|
||||
extern matrix4x4 m_matrix;
|
||||
extern float *m_upVector;
|
||||
|
||||
|
@ -220,5 +242,16 @@ int CM_BoxLeafnums( const vec3_t mins, const vec3_t maxs, int *list, int listsiz
|
|||
int CM_BoxBrushes( const vec3_t mins, const vec3_t maxs, cbrush_t **list, int listsize );
|
||||
cmodel_t *CM_TempBoxModel( const vec3_t mins, const vec3_t maxs, bool capsule );
|
||||
|
||||
//
|
||||
// cm_callbacks.c
|
||||
//
|
||||
int Callback_ContactBegin( const NewtonMaterial* material, const NewtonBody* body0, const NewtonBody* body1 );
|
||||
int Callback_ContactProcess( const NewtonMaterial* material, const NewtonContact* contact );
|
||||
void Callback_ContactEnd( const NewtonMaterial* material );
|
||||
|
||||
//
|
||||
// cm_materials.c
|
||||
//
|
||||
void CM_InitMaterials( void );
|
||||
|
||||
#endif//CM_LOCAL_H
|
|
@ -0,0 +1,100 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2007 ©
|
||||
// cm_materials.c - server materials system
|
||||
//=======================================================================
|
||||
|
||||
#include "cm_local.h"
|
||||
|
||||
bool CM_ParseMaterial( void )
|
||||
{
|
||||
uint num = cm.num_materials;
|
||||
|
||||
if( num > MAX_MATERIALS - 1 )
|
||||
{
|
||||
Msg( "materials limit exceeded\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!Com_MatchToken( "materialgroup" ))
|
||||
return false; // not a material description
|
||||
|
||||
Com_GetToken( false );
|
||||
if(Com_MatchToken( "default" ))
|
||||
num = 0; // write default material first
|
||||
|
||||
// member material name
|
||||
com.strncpy( cm.mat[num].name, com_token, MAX_STRING );
|
||||
|
||||
// setup default values
|
||||
while(!Com_MatchToken( "}" ))
|
||||
{
|
||||
if(!Com_GetToken( true ))
|
||||
return false; // unfinished material description
|
||||
|
||||
if( Com_MatchToken( "elasticity" ))
|
||||
{
|
||||
Com_GetToken( false );
|
||||
cm.mat[num].elasticity = com.atof( com_token );
|
||||
}
|
||||
else if( Com_MatchToken( "softness" ))
|
||||
{
|
||||
Com_GetToken( false );
|
||||
cm.mat[num].softness = com.atof( com_token );
|
||||
}
|
||||
else if( Com_MatchToken( "friction" ))
|
||||
{
|
||||
Com_GetToken( false );
|
||||
cm.mat[num].friction_static = com.atof( com_token );
|
||||
|
||||
if(Com_TryToken())
|
||||
cm.mat[num].friction_kinetic = com.atof( com_token );
|
||||
else cm.mat[num].friction_kinetic = cm.mat[num].friction_static; // same as static friction
|
||||
}
|
||||
}
|
||||
|
||||
// set default values if needed
|
||||
if( cm.mat[num].softness == 0.0f ) cm.mat[num].softness = cm.mat[0].softness;
|
||||
if( cm.mat[num].elasticity == 0.0f ) cm.mat[num].elasticity = cm.mat[0].elasticity;
|
||||
if( cm.mat[num].friction_static == 0.0f ) cm.mat[num].friction_static = cm.mat[0].friction_static;
|
||||
if( cm.mat[num].friction_kinetic == 0.0f ) cm.mat[num].friction_kinetic = cm.mat[0].friction_kinetic;
|
||||
|
||||
cm.num_materials++;
|
||||
|
||||
// material will be parsed sucessfully
|
||||
return true;
|
||||
}
|
||||
|
||||
void CM_InitMaterials( void )
|
||||
{
|
||||
bool load = Com_LoadScript( "scripts/materials.txt", NULL, 0 );
|
||||
int i, j;
|
||||
|
||||
if( !load )
|
||||
{
|
||||
// nothing to parse
|
||||
MsgDev( D_WARN, "scripts/materials.txt not found!\n" );
|
||||
return;
|
||||
}
|
||||
cm.num_materials = 0;
|
||||
memset( cm.mat, 0, sizeof(material_info_t) * MAX_MATERIALS );
|
||||
|
||||
while( Com_GetToken( true ))
|
||||
CM_ParseMaterial();
|
||||
|
||||
// assume IDs are in order and we don't need to remember them
|
||||
for ( i = 1; i < cm.num_materials; i++ )
|
||||
NewtonMaterialCreateGroupID( gWorld );
|
||||
|
||||
for ( i = 0; i < cm.num_materials; i++ )
|
||||
{
|
||||
for ( j = 0; j < cm.num_materials; j++ )
|
||||
{
|
||||
NewtonMaterialSetDefaultCollidable( gWorld, i, j, true );
|
||||
NewtonMaterialSetDefaultSoftness( gWorld, i, j, cm.mat[i].softness / 2.0f + cm.mat[j].softness / 2.0f );
|
||||
NewtonMaterialSetDefaultElasticity( gWorld, i, j, cm.mat[i].elasticity / 2.0f + cm.mat[j].elasticity / 2.0f );
|
||||
NewtonMaterialSetDefaultFriction( gWorld, i, j, cm.mat[i].friction_static / 2.0f + cm.mat[j].friction_static / 2.0f, cm.mat[i].friction_kinetic / 2.0f + cm.mat[j].friction_kinetic / 2.0f );
|
||||
NewtonMaterialSetCollisionCallback( gWorld, i, j, NULL, Callback_ContactBegin, Callback_ContactProcess, Callback_ContactEnd );
|
||||
}
|
||||
}
|
||||
Msg( "num materials %d\n", cm.num_materials );
|
||||
}
|
|
@ -14,7 +14,6 @@ float m_yawAngle;
|
|||
float m_maxTranslation;
|
||||
vec3_t m_size;
|
||||
vec3_t m_stepContact;
|
||||
vec3_t m_forceVector;
|
||||
matrix4x4 m_matrix;
|
||||
|
||||
|
||||
|
@ -37,6 +36,8 @@ typedef struct
|
|||
vec3_t forward, right, up;
|
||||
vec3_t previous_origin;
|
||||
vec3_t previous_velocity;
|
||||
|
||||
vec3_t movedir; // already aligned by world
|
||||
int previous_waterlevel;
|
||||
float impact_speed;
|
||||
trace_t groundtrace;
|
||||
|
@ -1607,9 +1608,9 @@ void CM_CmdUpdateForce( void )
|
|||
VectorNormalize( pml.right );
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
m_forceVector[i] = pml.forward[i] * fmove + pml.right[i] * smove;
|
||||
pml.movedir[i] = pml.forward[i] * fmove + pml.right[i] * smove;
|
||||
|
||||
ConvertDirectionToPhysic( m_forceVector );
|
||||
ConvertDirectionToPhysic( pml.movedir );
|
||||
|
||||
if( pm->cmd.upmove > 0.0f )
|
||||
{
|
||||
|
@ -1672,8 +1673,8 @@ void CM_ServerMove( pmove_t *pmove )
|
|||
float speed_factor;
|
||||
vec3_t tmp1, tmp2, result;
|
||||
|
||||
speed_factor = sqrt( DotProduct( m_forceVector, m_forceVector ) + 1.0e-6f );
|
||||
VectorScale( m_forceVector, 1.0f / speed_factor, heading );
|
||||
speed_factor = sqrt( DotProduct( pml.movedir, pml.movedir ) + 1.0e-6f );
|
||||
VectorScale( pml.movedir, 1.0f / speed_factor, heading );
|
||||
|
||||
VectorScale( heading, mass * 20.0f, tmp1 );
|
||||
VectorScale( heading, 2.0f * DotProduct( velocity, heading ), tmp2 );
|
||||
|
|
|
@ -23,6 +23,8 @@ bool InitPhysics( void )
|
|||
cmappool = Mem_AllocPool("CM Zone");
|
||||
gWorld = NewtonCreate( Palloc, Pfree ); // alloc world
|
||||
|
||||
CM_InitMaterials();
|
||||
|
||||
cm_noareas = Cvar_Get( "cm_noareas", "0", 0 );
|
||||
cm_use_triangles = Cvar_Get("cm_convert_polygons", "1", CVAR_INIT|CVAR_SYSTEMINFO );//, "convert bsp polygons to triangles, slowly but more safety way" );
|
||||
cm_solver_model = Cvar_Get("cm_solver", "0", CVAR_ARCHIVE );//, "change solver model: 0 - precision, 1 - adaptive, 2 - fast. (changes need restart server to take effect)" );
|
||||
|
|
|
@ -121,6 +121,10 @@ SOURCE=.\cm_debug.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cm_materials.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cm_model.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -145,11 +149,11 @@ SOURCE=.\cm_trace.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\physic.c
|
||||
SOURCE=.\cm_utils.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\cm_utils.c
|
||||
SOURCE=.\physic.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
|
|
@ -463,6 +463,7 @@ typedef struct physic_imp_s
|
|||
|
||||
void (*ClientMove)( sv_edict_t *ed );
|
||||
void (*Transform)( sv_edict_t *ed, matrix4x3 transform );
|
||||
void (*PlaySound)( sv_edict_t *ed, float volume, const char *sample );
|
||||
float *(*GetModelVerts)( sv_edict_t *ent, int *numvertices );
|
||||
} physic_imp_t;
|
||||
|
||||
|
|
Reference in New Issue