28 Nov 2008

This commit is contained in:
g-cont 2008-11-28 00:00:00 +03:00 committed by Alibek Omarov
parent 52a489fc55
commit ed5951a134
44 changed files with 4543 additions and 3866 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -5,9 +5,9 @@
#include "platform.h"
#include "byteorder.h"
#include "mathlib.h"
#include "const.h"
#include "utils.h"
#include "mathlib.h"
string wadoutname;
bool wad_append = false;

View File

@ -1,23 +1,7 @@
/*
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// cl_fx.c -- entity effects parsing and management
//=======================================================================
// Copyright XashXT Group 2008 ©
// cl_effects.c - entity effects parsing and management
//=======================================================================
#include "common.h"
#include "client.h"
@ -46,9 +30,9 @@ static int lastofs;
CL_ClearLightStyles
================
*/
void CL_ClearLightStyles (void)
void CL_ClearLightStyles( void )
{
Mem_Set (cl_lightstyle, 0, sizeof(cl_lightstyle));
Mem_Set( cl_lightstyle, 0, sizeof( cl_lightstyle ));
lastofs = -1;
}
@ -57,21 +41,20 @@ void CL_ClearLightStyles (void)
CL_RunLightStyles
================
*/
void CL_RunLightStyles (void)
void CL_RunLightStyles( void )
{
int ofs;
int i, ofs;
clightstyle_t *ls;
int i;
ofs = cl.time / 100;
if( ofs == lastofs ) return;
lastofs = ofs;
for( i = 0, ls = cl_lightstyle; i < MAX_LIGHTSTYLES; i++, ls++)
for( i = 0, ls = cl_lightstyle; i < MAX_LIGHTSTYLES; i++, ls++ )
{
if( !ls->length )
{
ls->value[0] = ls->value[1] = ls->value[2] = 1.0;
VectorSet( ls->value, 1.0f, 1.0f, 1.0f );
continue;
}
if( ls->length == 1 ) ls->value[0] = ls->value[1] = ls->value[2] = ls->map[0];
@ -92,7 +75,7 @@ void CL_SetLightstyle( int i )
cl_lightstyle[i].length = j;
for( k = 0; k < j; k++ )
cl_lightstyle[i].map[k] = (float)(s[k]-'a')/(float)('m'-'a');
cl_lightstyle[i].map[k] = (float)(s[k]-'a') / (float)('m'-'a');
}
/*
@ -124,9 +107,9 @@ cdlight_t cl_dlights[MAX_DLIGHTS];
CL_ClearDlights
================
*/
void CL_ClearDlights (void)
void CL_ClearDlights( void )
{
Mem_Set (cl_dlights, 0, sizeof(cl_dlights));
Mem_Set( cl_dlights, 0, sizeof( cl_dlights ));
}
/*
@ -135,59 +118,80 @@ CL_AllocDlight
===============
*/
cdlight_t *CL_AllocDlight (int key)
cdlight_t *CL_AllocDlight( int key )
{
int i;
cdlight_t *dl;
cdlight_t *dl;
// first look for an exact key match
if (key)
if( key )
{
dl = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
for( i = 0; i < MAX_DLIGHTS; i++, dl++ )
{
if (dl->key == key)
if( dl->key == key )
{
Mem_Set (dl, 0, sizeof(*dl));
Mem_Set( dl, 0, sizeof( *dl ));
dl->key = key;
return dl;
}
}
}
// then look for anything else
// then look for anything else
dl = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
for( i = 0; i < MAX_DLIGHTS; i++, dl++ )
{
if (dl->die < cl.time)
if( dl->die < cl.time )
{
Mem_Set (dl, 0, sizeof(*dl));
Mem_Set( dl, 0, sizeof( *dl ));
dl->key = key;
return dl;
}
}
dl = &cl_dlights[0];
Mem_Set (dl, 0, sizeof(*dl));
Mem_Set( dl, 0, sizeof( *dl ));
dl->key = key;
return dl;
}
/*
===============
CL_NewDlight
PF_addlight
void AddLight( vector pos, vector color, float radius, float decay, float time, float key )
===============
*/
void CL_NewDlight (int key, float x, float y, float z, float radius, float time)
void PF_addlight( void )
{
cdlight_t *dl;
cdlight_t *dl;
const float *pos, *col;
float radius, decay, time;
int key;
dl = CL_AllocDlight (key);
dl->origin[0] = x;
dl->origin[1] = y;
dl->origin[2] = z;
if( !VM_ValidateArgs( "AddLight", 6 ))
return;
pos = PRVM_G_VECTOR(OFS_PARM0);
col = PRVM_G_VECTOR(OFS_PARM1);
radius = PRVM_G_FLOAT(OFS_PARM2);
decay = PRVM_G_FLOAT(OFS_PARM3);
time = PRVM_G_FLOAT(OFS_PARM4);
key = (int)PRVM_G_FLOAT(OFS_PARM5);
if( radius <= 0 )
{
VM_Warning( "AddLight: ignore light with radius <= 0\n" );
return;
}
dl = CL_AllocDlight( key );
VectorCopy( pos, dl->origin );
VectorCopy( col, dl->color );
dl->die = cl.time + (time * 1000);
dl->decay = (decay * 1000);
dl->radius = radius;
dl->die = cl.time + time;
}
@ -197,25 +201,22 @@ CL_RunDLights
===============
*/
void CL_RunDLights (void)
void CL_RunDLights( void )
{
int i;
int i;
cdlight_t *dl;
dl = cl_dlights;
for (i=0 ; i<MAX_DLIGHTS ; i++, dl++)
for( i = 0; i < MAX_DLIGHTS; i++, dl++ )
{
if (!dl->radius)
continue;
if (dl->die < cl.time)
if( !dl->radius ) continue;
if( dl->die < cl.time )
{
dl->radius = 0;
return;
}
dl->radius -= cls.frametime*dl->decay;
if (dl->radius < 0)
dl->radius = 0;
dl->radius -= cls.frametime * dl->decay;
if( dl->radius < 0 ) dl->radius = 0;
}
}
@ -225,7 +226,7 @@ CL_AddDLights
===============
*/
void CL_AddDLights (void)
void CL_AddDLights( void )
{
int i;
cdlight_t *dl;
@ -237,7 +238,228 @@ void CL_AddDLights (void)
}
}
/*
==============================================================
DECALS MANAGEMENT
==============================================================
*/
#define MAX_DECALS 2048
#define DECAL_FADETIME (30 * 1000) // 30 seconds
#define DECAL_STAYTIME (120 * 1000) // 120 seconds
typedef struct cdecal_s
{
struct cdecal_s *prev, *next;
int time;
vec4_t modulate;
bool alphaFade;
shader_t shader;
int numVerts;
polyVert_t verts[MAX_VERTS_ON_POLY];
vec3_t origin;
} cdecal_t;
static cdecal_t cl_activeDecals;
static cdecal_t *cl_freeDecals;
static cdecal_t cl_decalList[MAX_DECALS];
/*
=================
CL_FreeDecal
=================
*/
static void CL_FreeDecal( cdecal_t *decal )
{
if( !decal->prev )
return;
decal->prev->next = decal->next;
decal->next->prev = decal->prev;
decal->next = cl_freeDecals;
cl_freeDecals = decal;
}
/*
=================
CL_AllocDecal
will always succeed, even if it requires freeing an old active mark
=================
*/
static cdecal_t *CL_AllocDecal( void )
{
cdecal_t *decal;
if( !cl_freeDecals )
CL_FreeDecal( cl_activeDecals.prev );
decal = cl_freeDecals;
cl_freeDecals = cl_freeDecals->next;
Mem_Set( decal, 0, sizeof( cdecal_t ));
decal->next = cl_activeDecals.next;
decal->prev = &cl_activeDecals;
cl_activeDecals.next->prev = decal;
cl_activeDecals.next = decal;
return decal;
}
/*
=================
CL_ClearDecals
=================
*/
void CL_ClearDecals( void )
{
int i;
Mem_Set( cl_decalList, 0, sizeof( cl_decalList ));
cl_activeDecals.next = &cl_activeDecals;
cl_activeDecals.prev = &cl_activeDecals;
cl_freeDecals = cl_decalList;
for( i = 0; i < MAX_DECALS - 1; i++ )
cl_decalList[i].next = &cl_decalList[i+1];
}
/*
=================
CL_AddDecal
called from render after clipping
=================
*/
void CL_AddDecal( vec3_t org, matrix3x3 m, shader_t s, vec4_t rgba, bool fade, decalFragment_t *df, const vec3_t *v )
{
cdecal_t *decal;
vec3_t delta;
int i;
decal = CL_AllocDecal();
VectorCopy( org, decal->origin );
decal->time = cl.time;
Vector4Copy( rgba, decal->modulate );
decal->alphaFade = fade;
decal->shader = s;
decal->numVerts = df->numVerts;
for( i = 0; i < df->numVerts; i++ )
{
VectorCopy( v[df->firstVert + i], decal->verts[i].point );
VectorSubtract( decal->verts[i].point, org, delta );
decal->verts[i].st[0] = 0.5 + DotProduct( delta, m[1] );
decal->verts[i].st[1] = 0.5 + DotProduct( delta, m[2] );
Vector4Copy( rgba, decal->verts[i].modulate );
}
}
/*
=================
CL_AddDecals
=================
*/
void CL_AddDecals( void )
{
cdecal_t *decal, *next;
int i, time, fadeTime;
float c;
fadeTime = DECAL_FADETIME; // 30 seconds
for( decal = cl_activeDecals.next; decal != &cl_activeDecals; decal = next )
{
// crab next now, so if the decal is freed we still have it
next = decal->next;
if( cl.time >= decal->time + DECAL_STAYTIME )
{
CL_FreeDecal( decal );
continue;
}
// HACKHACK: fade out glowing energy decals
if( decal->shader == re->RegisterShader( "particles/energy", SHADER_GENERIC ))
{
time = cl.time - decal->time;
if( time < fadeTime )
{
c = 1.0 - ((float)time / fadeTime);
for( i = 0; i < decal->numVerts; i++ )
{
decal->verts[i].modulate[0] = decal->modulate[0] * c;
decal->verts[i].modulate[1] = decal->modulate[1] * c;
decal->verts[i].modulate[2] = decal->modulate[2] * c;
}
}
}
// fade out with time
time = decal->time + DECAL_STAYTIME - cl.time;
if( time < fadeTime )
{
c = (float)time / fadeTime;
if( decal->alphaFade )
{
for( i = 0; i < decal->numVerts; i++ )
decal->verts[i].modulate[3] = decal->modulate[3] * c;
}
else
{
for( i = 0; i < decal->numVerts; i++ )
{
decal->verts[i].modulate[0] = decal->modulate[0] * c;
decal->verts[i].modulate[1] = decal->modulate[1] * c;
decal->verts[i].modulate[2] = decal->modulate[2] * c;
}
}
}
re->AddPolygon( decal->shader, decal->numVerts, decal->verts );
}
}
/*
===============
PF_adddecal
void AddDecal( vector org, vector dir, vector color, float rot, float radius, float alpha, float fade, float shader, float temp )
===============
*/
void PF_adddecal( void )
{
float *org, *dir, *col;
float rot, radius, alpha;
shader_t shader;
bool fade, temp;
vec4_t modulate;
if( !VM_ValidateArgs( "AddDecal", 9 ))
return;
VM_ValidateString( PRVM_G_STRING( OFS_PARM7 ));
org = PRVM_G_VECTOR(OFS_PARM0);
dir = PRVM_G_VECTOR(OFS_PARM1);
col = PRVM_G_VECTOR(OFS_PARM2);
rot = PRVM_G_FLOAT(OFS_PARM3);
radius = PRVM_G_FLOAT(OFS_PARM4);
alpha = PRVM_G_FLOAT(OFS_PARM5);
fade = (bool)PRVM_G_FLOAT(OFS_PARM6);
shader = re->RegisterShader( PRVM_G_STRING(OFS_PARM7), SHADER_GENERIC );
temp = (bool)PRVM_G_FLOAT(OFS_PARM8);
Vector4Set( modulate, col[0], col[1], col[2], alpha );
re->ImpactMark( org, dir, rot, radius, modulate, fade, shader, temp );
}
/*
==============================================================
@ -607,210 +829,9 @@ void PF_addparticle( void )
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
/*
===============
CL_ParticleEffect
Wall impact puffs
===============
*/
void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count)
{
int i, j;
cparticle_t *p;
float d;
for( i = 0; i < count; i++ )
{
p = CL_AllocParticle();
if( !p ) return;
p->time = cl.time;
VectorCopy( UnpackRGBA( color ), p->color );
d = rand()&31;
for( j = 0; j < 3; j++ )
{
p->org[j] = org[j] + ((rand()&7)-4) + d*dir[j];
p->vel[j] = RANDOM_FLOAT( -1.0f, 1.0f ) * 20;
}
p->accel[0] = p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY;
p->alpha = 1.0;
p->alphaVel = -1.0 / (0.5 + RANDOM_FLOAT(0, 1) * 0.3);
p->radius = 2;
p->radiusVel = 0;
p->length = 1;
p->lengthVel = 0;
p->rotation = 0;
}
}
/*
===============
CL_TeleportSplash
===============
*/
void CL_TeleportSplash( vec3_t org )
{
int i, j, k;
cparticle_t *p;
shader_t teleShader;
float vel, color;
vec3_t dir;
if( !cl_particles->integer )
return;
teleShader = re->RegisterShader( "particles/glow", SHADER_GENERIC );
for( i = -16; i < 16; i += 4 )
{
for( j = -16; j < 16; j += 4 )
{
for( k = -24; k < 32; k += 4 )
{
p = CL_AllocParticle();
if( !p ) return;
VectorSet( dir, j*8, i*8, k*8 );
VectorNormalizeFast( dir );
vel = 50 + (rand() & 63);
color = 0.1 + (0.2 * Com_RandomFloat( -1.0f, 1.0f ));
p->shader = teleShader;
p->time = cl.time;
p->flags = 0;
p->org[0] = org[0] + i + (rand() & 3);
p->org[1] = org[1] + j + (rand() & 3);
p->org[2] = org[2] + k + (rand() & 3);
p->vel[0] = dir[0] * vel;
p->vel[1] = dir[1] * vel;
p->vel[2] = dir[2] * vel;
p->accel[0] = 0;
p->accel[1] = 0;
p->accel[2] = -PARTICLE_GRAVITY;
p->color[0] = color;
p->color[1] = color;
p->color[2] = color;
p->colorVel[0] = 0;
p->colorVel[1] = 0;
p->colorVel[2] = 0;
p->alpha = 1.0;
p->alphaVel = -1.0 / (0.3 + (rand() & 7) * 0.02);
p->radius = 2;
p->radiusVel = 0;
p->length = 1;
p->lengthVel = 0;
p->rotation = 0;
}
}
}
}
/*
=================
CL_ExplosionParticles
=================
*/
void CL_ExplosionParticles( const vec3_t org )
{
cparticle_t *p;
int i, flags;
shader_t sparksShader;
shader_t smokeShader;
if( !cl_particles->integer )
return;
// sparks
flags = PARTICLE_STRETCH;
flags |= PARTICLE_BOUNCE;
flags |= PARTICLE_FRICTION;
sparksShader = re->RegisterShader( "particles/sparks", SHADER_GENERIC );
smokeShader = re->RegisterShader( "particles/smoke", SHADER_GENERIC );
for( i = 0; i < 384; i++ )
{
p = CL_AllocParticle();
if( !p ) return;
p->shader = sparksShader;
p->time = cl.time;
p->flags = flags;
p->org[0] = org[0] + ((rand() % 32) - 16);
p->org[1] = org[1] + ((rand() % 32) - 16);
p->org[2] = org[2] + ((rand() % 32) - 16);
p->vel[0] = (rand() % 512) - 256;
p->vel[1] = (rand() % 512) - 256;
p->vel[2] = (rand() % 512) - 256;
p->accel[0] = 0;
p->accel[1] = 0;
p->accel[2] = -60 + (30 * RANDOM_FLOAT( -1.0f, 1.0f ));
p->color[0] = 1.0;
p->color[1] = 1.0;
p->color[2] = 1.0;
p->colorVel[0] = 0;
p->colorVel[1] = 0;
p->colorVel[2] = 0;
p->alpha = 1.0;
p->alphaVel = -3.0;
p->radius = 0.5 + (0.2 * RANDOM_FLOAT( -1.0f, 1.0f ));
p->radiusVel = 0;
p->length = 8 + (4 * RANDOM_FLOAT( -1.0f, 1.0f ));
p->lengthVel = 8 + (4 * RANDOM_FLOAT( -1.0f, 1.0f ));
p->rotation = 0;
p->bounceFactor = 0.2;
VectorCopy( p->org, p->org2 );
}
// Smoke
flags = 0;
flags |= PARTICLE_VERTEXLIGHT;
for( i = 0; i < 5; i++ )
{
p = CL_AllocParticle();
if( !p ) return;
p->shader = smokeShader;
p->time = cl.time;
p->flags = flags;
p->org[0] = org[0] + RANDOM_FLOAT( -1.0f, 1.0f ) * 10;
p->org[1] = org[1] + RANDOM_FLOAT( -1.0f, 1.0f ) * 10;
p->org[2] = org[2] + RANDOM_FLOAT( -1.0f, 1.0f ) * 10;
p->vel[0] = RANDOM_FLOAT( -1.0f, 1.0f ) * 10;
p->vel[1] = RANDOM_FLOAT( -1.0f, 1.0f ) * 10;
p->vel[2] = RANDOM_FLOAT( -1.0f, 1.0f ) * 10 + (25 + RANDOM_FLOAT( -1.0f, 1.0f ) * 5);
p->accel[0] = 0;
p->accel[1] = 0;
p->accel[2] = 0;
p->color[0] = 0;
p->color[1] = 0;
p->color[2] = 0;
p->colorVel[0] = 0.75f;
p->colorVel[1] = 0.75f;
p->colorVel[2] = 0.75f;
p->alpha = 0.5f;
p->alphaVel = -(0.1 + RANDOM_FLOAT( 0.0f, 1.0f ) * 0.1f);
p->radius = 30 + (15 * RANDOM_FLOAT( -1.0f, 1.0f ));
p->radiusVel = 15 + (7.5 * RANDOM_FLOAT( -1.0f, 1.0f ));
p->length = 1;
p->lengthVel = 0;
p->rotation = rand() % 360;
}
}
/*
==============
CL_ClearEffects
==============
*/
void CL_ClearEffects( void )
@ -818,4 +839,5 @@ void CL_ClearEffects( void )
CL_ClearParticles ();
CL_ClearDlights ();
CL_ClearLightStyles ();
CL_ClearDecals ();
}

View File

@ -450,6 +450,7 @@ void CL_AddEntities( void )
CL_AddParticles();
CL_AddDLights();
CL_AddLightStyles();
CL_AddDecals();
}
//

View File

@ -54,7 +54,7 @@ bool CL_CheckOrDownloadFile( const char *filename )
if( f )
{
// it exists
int len = FS_Tell( f );
size_t len = FS_Tell( f );
cls.download = f;
// give the server an offset to start the download
@ -141,7 +141,7 @@ void CL_ParseDownload( sizebuf_t *msg )
if( r ) MsgDev( D_ERROR, "failed to rename.\n" );
cls.download = NULL;
Cvar_SetValue("scr_download", 0.0f );
Cvar_SetValue( "scr_download", 0.0f );
// get another file if needed
CL_RequestNextDownload();
@ -184,9 +184,9 @@ void CL_ParseServerData( sizebuf_t *msg )
str = MSG_ReadString( msg );
// get splash name
Cvar_Set( "cl_levelshot_name", va("background/%s.png", str ));
Cvar_Set( "cl_levelshot_name", va( "background/%s.png", str ));
Cvar_SetValue("scr_loading", 0.0f ); // reset progress bar
if(!FS_FileExists(va("gfx/%s", Cvar_VariableString("cl_levelshot_name"))))
if(!FS_FileExists( va("gfx/%s", Cvar_VariableString( "cl_levelshot_name" ))))
{
Cvar_Set("cl_levelshot_name", "common/black");
cl.make_levelshot = true; // make levelshot
@ -261,6 +261,19 @@ void CL_ParseConfigString( sizebuf_t *msg )
}
}
/*
================
CL_ParseSetAngle
set the view angle to this absolute value
================
*/
void CL_ParseSetAngle( sizebuf_t *msg )
{
cl.viewangles[0] = MSG_ReadAngle16( msg );
cl.viewangles[1] = MSG_ReadAngle16( msg );
cl.viewangles[2] = MSG_ReadAngle16( msg );
}
/*
=====================================================================
@ -328,14 +341,12 @@ void CL_ParseServerMessage( sizebuf_t *msg )
case svc_spawnbaseline:
CL_ParseBaseline( msg );
break;
/*
case svc_temp_entity:
CL_ParseTempEnts( msg );
break;
*/
case svc_download:
CL_ParseDownload( msg );
break;
case svc_setangle:
CL_ParseSetAngle( msg );
break;
case svc_frame:
CL_ParseFrame( msg );
break;

View File

@ -223,22 +223,22 @@ bool CL_LoadEdict( edict_t *ent )
return true;
}
void PF_BeginRead( void )
static void PF_BeginRead( void )
{
}
void PF_EndRead( void )
static void PF_EndRead( void )
{
}
void PF_ReadChar (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadChar( cls.multicast ); }
void PF_ReadShort (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadShort( cls.multicast ); }
void PF_ReadLong (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadLong( cls.multicast ); }
void PF_ReadFloat (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadFloat( cls.multicast ); }
void PF_ReadAngle (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadBits( cls.multicast, NET_FLOAT ); }
void PF_ReadCoord (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadBits( cls.multicast, NET_FLOAT ); }
void PF_ReadString (void){ PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString( MSG_ReadString( cls.multicast) ); }
void PF_ReadEntity (void){ VM_RETURN_EDICT( PRVM_PROG_TO_EDICT( MSG_ReadShort( cls.multicast ))); } // entindex
static void PF_ReadChar (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadChar( 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 ); }
static void PF_ReadAngle (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadBits( cls.multicast, NET_FLOAT ); }
static void PF_ReadCoord (void){ PRVM_G_FLOAT(OFS_RETURN) = MSG_ReadBits( cls.multicast, NET_FLOAT ); }
static void PF_ReadString (void){ PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString( MSG_ReadString( cls.multicast) ); }
static void PF_ReadEntity (void){ VM_RETURN_EDICT( PRVM_PROG_TO_EDICT( MSG_ReadShort( cls.multicast ))); } // entindex
/*
=========
@ -247,7 +247,7 @@ PF_drawfield
void DrawField( float value, vector pos, vector size )
=========
*/
void PF_drawfield( void )
static void PF_drawfield( void )
{
char num[16], *ptr;
int l, frame;
@ -286,7 +286,7 @@ PF_drawnet
void DrawNet( vector pos, string image )
=========
*/
void PF_drawnet( void )
static void PF_drawnet( void )
{
float *pos;
shader_t shader;
@ -310,7 +310,7 @@ PF_drawfps
void DrawFPS( vector pos )
=========
*/
void PF_drawfps( void )
static void PF_drawfps( void )
{
float calc;
static double nexttime = 0, lasttime = 0;
@ -358,7 +358,7 @@ PF_drawcenterprint
void DrawCenterPrint( void )
=========
*/
void PF_drawcenterprint( void )
static void PF_drawcenterprint( void )
{
char *start;
int l, x, y, w;
@ -411,7 +411,7 @@ PF_centerprint
void HUD_CenterPrint( string text, float y, float charwidth )
=========
*/
void PF_centerprint( void )
static void PF_centerprint( void )
{
float y, width;
const char *text;
@ -448,7 +448,7 @@ PF_levelshot
float HUD_MakeLevelShot( void )
=========
*/
void PF_levelshot( void )
static void PF_levelshot( void )
{
PRVM_G_FLOAT(OFS_RETURN) = 0;
if(!VM_ValidateArgs( "HUD_MakeLevelShot", 0 ))
@ -472,7 +472,7 @@ PF_setcolor
void HUD_SetColor( vector rgb, float alpha )
=========
*/
void PF_setcolor( void )
static void PF_setcolor( void )
{
float *rgb, alpha;
@ -488,36 +488,112 @@ void PF_setcolor( void )
=========
PF_startsound
CL_StartSound( vector pos, entity e, float chan, float sfx, float vol, float attn )
void CL_StartSound( vector pos, entity e, float chan, float sfx, float vol, float attn, float localsound )
=========
*/
void PF_startsound( void )
static void PF_startsound( void )
{
float volume;
int channel;
int sound_num;
sound_t sound_num;
int attenuation;
float *pos = NULL;
bool client_sound;
int ent = 0;
if( !VM_ValidateArgs( "CL_StartSound", 6 ))
if( !VM_ValidateArgs( "CL_StartSound", 7 ))
return;
pos = PRVM_G_VECTOR(OFS_PARM0);
ent = PRVM_G_EDICTNUM(OFS_PARM1);
channel = (int)PRVM_G_FLOAT(OFS_PARM2);
sound_num = (int)PRVM_G_FLOAT(OFS_PARM3);
sound_num = (sound_t)PRVM_G_FLOAT(OFS_PARM3);
volume = PRVM_G_FLOAT(OFS_PARM4);
attenuation = (int)PRVM_G_FLOAT(OFS_PARM5);
if( !cl.sound_precache[sound_num] )
client_sound = (bool)PRVM_G_FLOAT(OFS_PARM6);
if( client_sound )
{
VM_Warning( "CL_StartSound: invalid sound index: %i\n", sound_num );
return;
S_StartSound( pos, ent, channel, sound_num, volume, attenuation );
}
S_StartSound( pos, ent, channel, cl.sound_precache[sound_num], volume, attenuation );
else if( cl.sound_precache[sound_num] )
{
S_StartSound( pos, ent, channel, cl.sound_precache[sound_num], volume, attenuation );
}
else VM_Warning( "CL_StartSound: can't play sound with index %i\n", sound_num );
}
//NOTE: intervals between various "interfaces" was leave for future expansions
/*
=========
PF_pointcontents
float CL_PointContents( vector point )
=========
*/
static void PF_pointcontents( void )
{
if( !VM_ValidateArgs( "CL_PointContents", 1 ))
return;
PRVM_G_FLOAT(OFS_RETURN) = CL_PointContents(PRVM_G_VECTOR(OFS_PARM0));
}
/*
=========
PF_startsound
sound_t CL_PrecacheSound( string samp )
=========
*/
static void PF_precachesound( void )
{
if( !VM_ValidateArgs( "CL_PrecacheSound", 1 ))
return;
VM_ValidateString(PRVM_G_STRING(OFS_PARM0));
PRVM_G_FLOAT(OFS_RETURN) = S_RegisterSound(PRVM_G_STRING(OFS_PARM0));
}
/*
=================
PF_findexplosionplane
vector CL_FindExplosionPlane( vector org, float radius )
=================
*/
static void PF_findexplosionplane( void )
{
static vec3_t planes[6] = {{0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 0, -1}, {0, -1, 0}, {-1, 0, 0}};
trace_t trace;
float best = 1.0, radius;
vec3_t point, dir;
const float *org;
int i;
if( !VM_ValidateArgs( "CL_FindExplosionPlane", 2 ))
return;
org = PRVM_G_VECTOR(OFS_PARM0);
radius = PRVM_G_FLOAT(OFS_PARM1);
VectorClear( dir );
for( i = 0; i < 6; i++ )
{
VectorMA( org, radius, planes[i], point );
trace = CL_Trace( org, vec3_origin, vec3_origin, point, MOVE_WORLDONLY, NULL, MASK_SOLID );
if( trace.allsolid || trace.fraction == 1.0 )
continue;
if( trace.fraction < best )
{
best = trace.fraction;
VectorCopy( trace.plane.normal, dir );
}
}
VectorCopy( dir, PRVM_G_VECTOR( OFS_RETURN ));
}
// NOTE: intervals between various "interfaces" was leave for future expansions
prvm_builtin_t vm_cl_builtins[] =
{
NULL, // #0 (leave blank as default, but can include easter egg )
@ -642,8 +718,18 @@ 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 pos, entity e, float chan, float sfx, float vol, float attn )
PF_startsound, // #127 void CL_StartSound( vector, entity, 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 )
PF_adddecal, // #131 void AddDecal( vector, vector, vector, float, float, float, float, string, float )
PF_addlight, // #132 void AddLight( vector pos, vector col, float rad, float decay, float time, float key )
NULL, // #133
NULL, // #134
NULL, // #135
NULL, // #136
NULL, // #137
PF_findexplosionplane, // #138 vector CL_FindExplosionPlane( vector org, float radius )
};
const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t); //num of builtins

View File

@ -1,122 +0,0 @@
/*
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// cl_tent.c -- client side temporary entities
#include "common.h"
#include "client.h"
// temp entity events
typedef enum
{
TE_TELEPORT = 0,
TE_SPIKE,
TE_SPARKS,
TE_GUNSHOT,
TE_SUPERSPIKE,
TE_EXPLOSION,
TE_LIGHTNING1,
TE_LIGHTNING2,
TE_LIGHTNING3,
TE_LAVASPLASH,
TE_BLOOD
} temp_event_t;
/*
=================
CL_FindExplosionPlane
Disgusting hack
=================
*/
static void CL_FindExplosionPlane( const vec3_t org, float radius, vec3_t dir )
{
static vec3_t planes[6] = {{0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 0, -1}, {0, -1, 0}, {-1, 0, 0}};
trace_t trace;
vec3_t point;
float best = 1.0;
int i;
VectorClear( dir );
for( i = 0; i < 6; i++ )
{
VectorMA( org, radius, planes[i], point );
trace = CL_Trace( org, vec3_origin, vec3_origin, point, MOVE_WORLDONLY, NULL, MASK_SOLID );
if( trace.allsolid || trace.fraction == 1.0 )
continue;
if( trace.fraction < best )
{
best = trace.fraction;
VectorCopy( trace.plane.normal, dir );
}
}
}
/*
=================
CL_ParseTempEnts
=================
*/
void CL_ParseTempEnts( sizebuf_t *msg )
{
int type;
vec3_t pos, dir;
sound_t sound_fx;
shader_t sfx_1, sfx_2;
type = MSG_ReadByte( msg );
switch( type )
{
case TE_TELEPORT:
MSG_ReadPos( msg, pos );
CL_TeleportSplash( pos );
break;
case TE_BLOOD: // bullet hitting flesh
MSG_ReadPos(msg, pos);
MSG_ReadPos(msg, dir);
CL_ParticleEffect( pos, dir, 0xe8, 60 );
break;
case TE_SPIKE:
MSG_ReadPos(msg, pos);
break;
case TE_GUNSHOT: // bullet hitting wall
MSG_ReadPos(msg, pos);
CL_ParticleEffect( pos, dir, 0, 40 );
break;
case TE_EXPLOSION:
MSG_ReadPos(msg, pos);
CL_FindExplosionPlane( pos, 40, dir );
sfx_1 = re->RegisterShader( "engine/explosion", SHADER_GENERIC );
sfx_2 = re->RegisterShader( "engine/{scorch", SHADER_GENERIC );
// CL_Explosion( pos, dir, 40, rand() % 360, 350, 1.0, 0.5, 0.5, sfx_1 );
CL_ExplosionParticles( pos );
// CL_ImpactMark( pos, dir, rand() % 360, 40, 1, 1, 1, 1, false, sfx_2, false );
sound_fx = S_RegisterSound( "weapons/r_exp3.wav" );
S_StartSound( pos, 0, CHAN_AUTO, sound_fx, 1.0f, ATTN_NORM );
break;
default:
Host_Error( "CL_ParseTEnt: bad type %i\n", type );
break;
}
}

View File

@ -334,7 +334,6 @@ typedef struct
int key; // so entities can reuse same entry
float die; // stop lighting after this time
float decay; // drop this each second
float minlight; // don't add when contributing less
} cdlight_t;
extern cdlight_t cl_dlights[MAX_DLIGHTS];
@ -541,14 +540,17 @@ void CL_AddLoopingSounds( void );
//
// cl_fx.c
//
cdlight_t *CL_AllocDlight (int key);
void CL_AddParticles (void);
cdlight_t *CL_AllocDlight( int key );
void CL_AddParticles( void );
void CL_AddDecals( void );
void CL_ClearEffects( void );
void CL_StudioEvent( dstudioevent_t *event, entity_state_t *ent );
void CL_ExplosionParticles( const vec3_t org );
void CL_AddDecal( vec3_t org, matrix3x3 m, shader_t s, vec4_t rgba, bool fade, decalFragment_t *df, const vec3_t *v );
entity_state_t *CL_GetEdictByIndex( int index );
entity_state_t *CL_GetLocalPlayer( void );
void PF_addlight( void );
void PF_addparticle( void );
void PF_adddecal( void );
//
// cl_pred.c
@ -558,7 +560,6 @@ void CL_PredictMovement (void);
//
// cl_con.c
//
int Con_PrintStrlen( const char *string );
bool Con_Active( void );
void Con_CheckResize( void );
void Con_Print( const char *txt );

View File

@ -323,7 +323,6 @@ 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 );
bool SV_ReadComment( char *comment, int savenum );
int CL_PMpointcontents( vec3_t point );
void CL_MouseEvent( int mx, int my, int time );

View File

@ -61,6 +61,7 @@ enum svc_ops_e
svc_packetentities, // [...]
svc_deltapacketentities, // [...]
svc_frame, // server frame
svc_setangle, // [short short short] set the view angle to this absolute value
};
// client to server
@ -187,6 +188,8 @@ void MSG_BeginReading (sizebuf_t *sb);
#define MSG_ReadShort( x) _MSG_ReadBits( x, NET_SHORT, __FILE__, __LINE__ )
#define MSG_ReadWord( x ) _MSG_ReadBits( x, NET_WORD, __FILE__, __LINE__ )
#define MSG_ReadLong( x ) _MSG_ReadBits( x, NET_LONG, __FILE__, __LINE__ )
#define MSG_ReadAngle16( x ) _MSG_ReadBits( x, NET_ANGLE, __FILE__, __LINE__ )
#define MSG_ReadAngle32( x ) _MSG_ReadBits( x, NET_FLOAT, __FILE__, __LINE__ )
float MSG_ReadFloat( sizebuf_t *msg );
char *MSG_ReadString( sizebuf_t *sb );
char *MSG_ReadStringLine( sizebuf_t *sb );

View File

@ -126,11 +126,11 @@ SOURCE=.\client\cl_demo.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_frame.c
SOURCE=.\client\cl_effects.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_fx.c
SOURCE=.\client\cl_frame.c
# End Source File
# Begin Source File
@ -158,10 +158,6 @@ SOURCE=.\client\cl_scrn.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_tent.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_view.c
# End Source File
# Begin Source File

View File

@ -79,6 +79,7 @@ void Host_InitRender( void )
// studio callbacks
ri.UpdateScreen = SCR_UpdateScreen;
ri.StudioEvent = CL_StudioEvent;
ri.AddDecal = CL_AddDecal;
ri.ShowCollision = pe->DrawCollision;
ri.GetClientEdict = CL_GetEdictByIndex;
ri.GetLocalPlayer = CL_GetLocalPlayer;

View File

@ -121,9 +121,6 @@ typedef struct sv_client_s
usercmd_t lastcmd; // for filling in big drops
usercmd_t cmd; // current user commands
vec3_t fix_angles; // q1 legacy
bool fixangle;
int ping;
int rate;
int surpressCount; // number of messages rate supressed
@ -316,7 +313,7 @@ bool SV_CheckBottom (edict_t *ent);
//
// sv_move.c
//
void SV_Transform( sv_edict_t *ed, matrix4x3 transform );
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 );
bool SV_movestep( edict_t *ent, vec3_t move, bool relink, bool noenemy, bool settrace );

View File

@ -534,7 +534,7 @@ void SV_PutClientInServer( edict_t *ent )
viewmodel->priv.sv->s.classname = SV_ClassIndex(PRVM_GetString(viewmodel->progs.sv->classname));
SV_LinkEdict( ent ); // m_pmatrix calculated here, so we need call this before pe->CreatePlayer
ent->priv.sv->physbody = pe->CreatePlayer( ent->priv.sv, SV_GetModelPtr( ent ), ent->progs.sv->m_pmatrix );
ent->priv.sv->physbody = pe->CreatePlayer( ent->priv.sv, SV_GetModelPtr( ent ), ent->progs.sv->origin, ent->progs.sv->m_pmatrix );
}
/*

View File

@ -68,7 +68,7 @@ struct sv_entvars_s
vec3_t velocity;
vec3_t avelocity;
vec3_t m_pcentre[3];
vec3_t m_pmatrix[4];
vec3_t m_pmatrix[3];
vec3_t movedir;
vec3_t force;
vec3_t torque;
@ -96,22 +96,22 @@ struct sv_entvars_s
float sequence;
float animtime;
float framerate;
float style;
float effects;
float renderfx;
float rendermode;
float renderamt;
vec3_t rendercolor;
float colormap;
float gaitsequence;
float colormap;
float style;
float flags;
float aiflags;
float spawnflags;
float blending[16];
float controller[16];
float fixangle;
float blending[16];
vec3_t v_angle;
vec3_t view_ofs;
float fixangle;
vec3_t punchangle;
float button0;
float button1;
@ -120,14 +120,14 @@ struct sv_entvars_s
float weapon;
float items;
float currentammo;
string_t v_model;
float v_sequence;
float v_frame;
string_t v_model;
float v_body;
float v_skin;
float v_sequence;
string_t p_model;
float p_sequence;
float p_frame;
string_t p_model;
float p_body;
float p_skin;
string_t loopsound;
@ -152,6 +152,6 @@ struct sv_entvars_s
float team;
};
#define PROG_CRC_SERVER 16873
#define PROG_CRC_SERVER 3519
#endif//SV_EDICT_H

View File

@ -96,6 +96,21 @@ void SV_UpdateEntityState( edict_t *ent )
ent->priv.sv->s.model.colormap = ent->progs.sv->colormap = client->progs.sv->colormap;
ent->priv.sv->s.effects |= EF_MINLIGHT; // always have some light
}
else if( ent->priv.sv->s.ed_type == ED_CLIENT )
{
if( ent->progs.sv->fixangle )
{
// FIXME: set angles
//for( i = 0; i < 3; i++ )
// ent->priv.sv->s.delta_angles[i] = ANGLE2SHORT( ent->priv.sv->s.angles[i] );
//VectorClear( ent->priv.sv->s.angles );
//VectorClear( ent->priv.sv->s.viewangles );
//VectorClear( ent->progs.sv->v_angle );
// and clear fixangle for the next frame
ent->progs.sv->fixangle = 0;
}
}
else if( ent->priv.sv->s.ed_type == ED_AMBIENT )
{
if( ent->progs.sv->solid == SOLID_TRIGGER )

View File

@ -400,30 +400,37 @@ float *SV_GetModelVerts( sv_edict_t *ed, int *numvertices )
return NULL;
}
void SV_Transform( sv_edict_t *ed, matrix4x3 transform )
void SV_Transform( sv_edict_t *ed, const vec3_t origin, const matrix3x3 matrix )
{
edict_t *edict;
vec3_t origin, angles;
matrix4x4 objmatrix;
vec3_t angles;
if(!ed) return;
if( !ed ) return;
edict = PRVM_EDICT_NUM( ed->serialnumber );
// save matrix (fourth value will be reset on save\load)
VectorCopy( transform[0], edict->progs.sv->m_pmatrix[0] );
VectorCopy( transform[1], edict->progs.sv->m_pmatrix[1] );
VectorCopy( transform[2], edict->progs.sv->m_pmatrix[2] );
VectorCopy( transform[3], edict->progs.sv->m_pmatrix[3] );
Matrix4x4_LoadIdentity( objmatrix );
VectorCopy( transform[0], objmatrix[0] );
VectorCopy( transform[1], objmatrix[1] );
VectorCopy( transform[2], objmatrix[2] );
VectorCopy( transform[3], objmatrix[3] );
MatrixAngles( objmatrix, origin, angles );
Matrix3x3_Transpose( edict->progs.sv->m_pmatrix, matrix );
#if 0
edict->progs.sv->m_pmatrix[0][0] = matrix[0][0];
edict->progs.sv->m_pmatrix[0][1] = matrix[0][2];
edict->progs.sv->m_pmatrix[0][2] = matrix[0][1];
edict->progs.sv->m_pmatrix[1][0] = matrix[1][0];
edict->progs.sv->m_pmatrix[1][1] = matrix[1][2];
edict->progs.sv->m_pmatrix[1][2] = matrix[1][1];
edict->progs.sv->m_pmatrix[2][0] = matrix[2][0];
edict->progs.sv->m_pmatrix[2][1] = matrix[2][2];
edict->progs.sv->m_pmatrix[2][2] = matrix[2][1];
Matrix3x3_ConcatRotate( edict->progs.sv->m_pmatrix, -90, 1, 0, 0 );
Matrix3x3_ConcatRotate( edict->progs.sv->m_pmatrix, 180, 0, 1, 0 );
Matrix3x3_ConcatRotate( edict->progs.sv->m_pmatrix, 90, 0, 0, 1 );
Matrix3x3_ToAngles( edict->progs.sv->m_pmatrix, angles );
#endif
VectorCopy( origin, edict->progs.sv->origin );
VectorCopy( angles, edict->progs.sv->angles );
MatrixAngles( edict->progs.sv->m_pmatrix, angles );
edict->progs.sv->angles[0] = angles[0];
edict->progs.sv->angles[1] = angles[1];
edict->progs.sv->angles[2] = angles[2];
// refresh force and torque
pe->GetForce( ed->physbody, edict->progs.sv->velocity, edict->progs.sv->avelocity, edict->progs.sv->force, edict->progs.sv->torque );

View File

@ -1689,15 +1689,6 @@ void SV_Physics_ClientEntity( edict_t *ent )
prog->globals.sv->time = sv.time;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(ent);
PRVM_ExecuteProgram( prog->globals.sv->PlayerPostThink, "PlayerPostThink" );
if( ent->progs.sv->fixangle )
{
// angle fixing was requested by physics code...
// so store the current angles for later use
VectorCopy( ent->progs.sv->angles, client->fix_angles );
ent->progs.sv->fixangle = false;// and clear fixangle for the next frame
client->fixangle = true;
}
}
void SV_Physics_ClientMove( sv_client_t *client, usercmd_t *cmd )
@ -1738,15 +1729,6 @@ void SV_Physics_ClientMove( sv_client_t *client, usercmd_t *cmd )
prog->globals.sv->pev = PRVM_EDICT_TO_PROG( ent );
PRVM_ExecuteProgram( prog->globals.sv->PlayerPostThink, "PlayerPostThink" );
prog->globals.sv->frametime = sv.frametime;
if( ent->progs.sv->fixangle )
{
// angle fixing was requested by physics code...
// so store the current angles for later use
VectorCopy( ent->progs.sv->angles, client->fix_angles );
ent->progs.sv->fixangle = false;// and clear fixangle for the next frame
client->fixangle = true;
}
}
/*

View File

@ -6,6 +6,7 @@
#include "common.h"
#include "server.h"
#include "byteorder.h"
#include "matrix_lib.h"
#include "const.h"
/*
@ -134,7 +135,7 @@ static trace_t SV_TraceToss( edict_t *tossent, edict_t *ignore)
void SV_CreatePhysBody( edict_t *ent )
{
if( !ent || ent->progs.sv->movetype != MOVETYPE_PHYSIC ) return;
ent->priv.sv->physbody = pe->CreateBody( ent->priv.sv, SV_GetModelPtr(ent), ent->progs.sv->m_pmatrix, ent->progs.sv->solid );
ent->priv.sv->physbody = pe->CreateBody( ent->priv.sv, SV_GetModelPtr(ent), ent->progs.sv->origin, ent->progs.sv->m_pmatrix, ent->progs.sv->solid );
pe->SetParameters( ent->priv.sv->physbody, SV_GetModelPtr(ent), 0, ent->progs.sv->mass );
}
@ -166,13 +167,12 @@ 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.0f;
angles[0] = ent->progs.sv->angles[0] + 90;
angles[1] = ent->progs.sv->angles[1];
angles[2] = ent->progs.sv->angles[2] + 90.0f;
angles[2] = ent->progs.sv->angles[2] - 90;
AngleVectors( angles, ent->progs.sv->m_pmatrix[0], ent->progs.sv->m_pmatrix[1], ent->progs.sv->m_pmatrix[2] );
VectorCopy( ent->progs.sv->origin, ent->progs.sv->m_pmatrix[3] );
ConvertPositionToPhysic( ent->progs.sv->m_pmatrix[3] );
Matrix3x3_FromAngles( angles, ent->progs.sv->m_pmatrix );
Matrix3x3_Transpose( ent->progs.sv->m_pmatrix, ent->progs.sv->m_pmatrix );
SV_CreatePhysBody( ent );
}
@ -2055,7 +2055,7 @@ PF_lightstyle
void lightstyle( float style, string value )
===============
*/
void PF_lightstyle( void )
static void PF_lightstyle( void )
{
int style;
const char *val;
@ -2078,7 +2078,7 @@ PF_pointcontents
float pointcontents( vector v )
=============
*/
void PF_pointcontents( void )
static void PF_pointcontents( void )
{
if(!VM_ValidateArgs( "pointcontents", 1 )) return;
PRVM_G_FLOAT(OFS_RETURN) = SV_PointContents(PRVM_G_VECTOR(OFS_PARM0));

View File

@ -1,41 +1,6 @@
#include "common.h"
#include "server.h"
/*
==============
ClientThink
This will be called once for each client frame, which will
usually be a couple times for each server frame.
==============
*/
void ClientThink (edict_t *ent, usercmd_t *ucmd)
{
edict_t *other;
int i, j;
pmove_t pm;
for (i = 0; i < pm.numtouch; i++)
{
other = pm.touchents[i];
for (j = 0; j < i; j++)
{
if (pm.touchents[j] == other)
break;
}
if (j != i) continue; // duplicated
if (!other->progs.sv->touch) continue;
prog->globals.sv->pev = PRVM_EDICT_TO_PROG(other);
prog->globals.sv->other = PRVM_EDICT_TO_PROG(ent);
prog->globals.sv->time = sv.time;
if( other->progs.sv->touch )
{
PRVM_ExecuteProgram (other->progs.sv->touch, "pev->touch");
}
}
}
/*
==================
SV_StartParticle

View File

@ -413,7 +413,12 @@ bool Image_LoadMIP( const char *name, const byte *buffer, size_t filesize )
// qlumpy used this color for transparent textures, otherwise it's decals
if( pal[255*3+0] == 0 && pal[255*3+1] == 0 && pal[255*3+2] == 255 );
else image.flags |= IMAGE_COLORINDEX;
else if( Sys.app_name == HOST_NORMAL )
{
// render requires setup special palette
image.flags |= IMAGE_COLORINDEX;
rendermode = LUMP_DECAL;
}
image.flags |= IMAGE_HAS_ALPHA;
}
else rendermode = LUMP_NORMAL;

View File

@ -93,19 +93,17 @@ void Callback_PmoveApplyForce( const NewtonBody* body )
pi.ClientMove((sv_edict_t *)NewtonBodyGetUserData( body ));
}
void Callback_ApplyTransform( const NewtonBody* body, const float* matrix )
void Callback_ApplyTransform( const NewtonBody* body, const float* src )
{
sv_edict_t *edict = (sv_edict_t *)NewtonBodyGetUserData( body );
matrix4x4 objcoords;
matrix4x3 translate;// obj matrix
matrix4x4 tmp;
matrix3x3 dst;
vec3_t origin;
// convert matrix4x4 into 4x3
// Matrix4x4_FromArrayFloatGL( objcoords, matrix );
Mem_Copy( objcoords, matrix, sizeof(objcoords));
VectorCopy( objcoords[0], translate[0] );
VectorCopy( objcoords[1], translate[1] );
VectorCopy( objcoords[2], translate[2] );
VectorCopy( objcoords[3], translate[3] );
Matrix4x4_FromArrayFloatGL( tmp, src );
Matrix4x4_OriginFromMatrix( tmp, origin );
Matrix4x4_ToMatrix3x3( dst, tmp );
ConvertPositionToGame( origin );
pi.Transform( edict, translate );
pi.Transform( edict, origin, dst );
}

View File

@ -238,7 +238,7 @@ void CM_ClientMove( pmove_t *pmove )
}
physbody_t *Phys_CreatePlayer( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform )
physbody_t *Phys_CreatePlayer( sv_edict_t *ed, cmodel_t *mod, const vec3_t origin, const matrix3x3 matrix )
{
NewtonCollision *col, *hull;
NewtonBody *body;
@ -267,7 +267,8 @@ physbody_t *Phys_CreatePlayer( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transfor
m_maxTranslation = m_size[0] * 0.25f;
m_maxStepHigh = -m_size[2] * 0.5f;
VectorCopy( transform[3], trans[3] ); // copy position only
VectorCopy( origin, trans[3] ); // copy position only
ConvertPositionToPhysic( trans[3] );
trans[3][1] = CM_FindFloor( trans[3], 32768 ) + radius[2]; // merge floor position

View File

@ -8,7 +8,7 @@
#include "matrix_lib.h"
#include "cm_utils.h"
physbody_t *Phys_CreateBody( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform, int solid )
physbody_t *Phys_CreateBody( sv_edict_t *ed, cmodel_t *mod, const vec3_t origin, const matrix3x3 matrix, int solid )
{
NewtonCollision *col;
NewtonBody *body;
@ -55,10 +55,11 @@ physbody_t *Phys_CreateBody( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform,
VectorScale( center, 0.5, offset[3] );
// setup translation matrix
VectorCopy( transform[0], trans[0] );
VectorCopy( transform[1], trans[1] );
VectorCopy( transform[2], trans[2] );
VectorCopy( transform[3], trans[3] );
VectorCopy( matrix[0], trans[0] );
VectorCopy( matrix[1], trans[1] );
VectorCopy( matrix[2], trans[2] );
VectorCopy( origin, trans[3] );
ConvertPositionToPhysic( trans[3] );
switch(solid)
{

View File

@ -44,8 +44,8 @@ void Phys_Frame( float time );
//
// cm_rigidbody.c
//
physbody_t *Phys_CreateBody( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform, int solid );
physbody_t *Phys_CreatePlayer( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform );
physbody_t *Phys_CreateBody( sv_edict_t *ed, cmodel_t *mod, const vec3_t origin, const matrix3x3 matrix, int solid );
physbody_t *Phys_CreatePlayer( sv_edict_t *ed, cmodel_t *mod, const vec3_t origin, const matrix3x3 matrix );
void Phys_SetParameters( physbody_t *body, cmodel_t *mod, int material, float mass );
bool Phys_GetForce( physbody_t *body, vec3_t velocity, vec3_t avelocity, vec3_t force, vec3_t torque );
void Phys_SetForce( physbody_t *body, vec3_t velocity, vec3_t avelocity, vec3_t force, vec3_t torque );

View File

@ -15,6 +15,7 @@
#define MAX_MODELS 4096 // total count of brush & studio various models per one map
#define MAX_PARTICLES 32768 // pre one frame
#define MAX_EDICTS 65535 // absolute limit that never be reached, (do not edit!)
#define MAX_VERTS_ON_POLY 10 // decal vertices
// engine edict types
typedef enum

View File

@ -50,8 +50,6 @@ typedef struct ui_globalvars_s ui_globalvars_t;
typedef struct physbody_s physbody_t;
// FIXME: get rid of this
typedef vec_t matrix3x4[3][4];
typedef vec_t matrix4x3[4][3];
typedef vec_t gl_matrix[16];
#ifndef NULL

View File

@ -380,7 +380,7 @@ _inline void AngleVectorsFLU(const vec3_t angles, vec3_t forward, vec3_t left, v
}
// FIXME: get rid of this
_inline void MatrixAngles( matrix4x4 matrix, vec3_t origin, vec3_t angles )
_inline void MatrixAngles( matrix3x3 matrix, vec3_t angles )
{
vec3_t forward, right, up;
float xyDist;
@ -393,7 +393,7 @@ _inline void MatrixAngles( matrix4x4 matrix, vec3_t origin, vec3_t angles )
right[2] = matrix[1][1];
up[2] = matrix[2][1];
xyDist = sqrt( forward[0] * forward[0] + forward[1] * forward[1] );
xyDist = com.sqrt( forward[0] * forward[0] + forward[1] * forward[1] );
if ( xyDist > EQUAL_EPSILON ) // enough here to get angles?
{
@ -407,8 +407,6 @@ _inline void MatrixAngles( matrix4x4 matrix, vec3_t origin, vec3_t angles )
angles[0] = RAD2DEG( atan2( -forward[2], xyDist ) );
angles[2] = 0;
}
VectorCopy(matrix[3], origin );// extract origin
ConvertPositionToGame( origin );
}
/*

View File

@ -1075,6 +1075,45 @@ _inline void Matrix4x4_FromArrayFloatGL( matrix4x4 out, const float in[16] )
#endif
}
_inline void Matrix4x4_FromArrayFloatD3D( matrix4x4 out, const float in[16] )
{
#ifdef OPENGL_STYLE
out[0][0] = in[0];
out[1][0] = in[1];
out[2][0] = in[2];
out[3][0] = in[3];
out[0][1] = in[4];
out[1][1] = in[5];
out[2][1] = in[6];
out[3][1] = in[7];
out[0][2] = in[8];
out[1][2] = in[9];
out[2][2] = in[10];
out[3][2] = in[11];
out[0][3] = in[12];
out[1][3] = in[13];
out[2][3] = in[14];
out[3][3] = in[15];
#else
out[0][0] = in[0];
out[0][1] = in[1];
out[0][2] = in[2];
out[0][3] = in[3];
out[1][0] = in[4];
out[1][1] = in[5];
out[1][2] = in[6];
out[1][3] = in[7];
out[2][0] = in[8];
out[2][1] = in[9];
out[2][2] = in[10];
out[2][3] = in[11];
out[3][0] = in[12];
out[3][1] = in[13];
out[3][2] = in[14];
out[3][3] = in[15];
#endif
}
_inline void Matrix4x4_ToMatrix3x3( matrix3x3 out, const matrix4x4 in )
{
out[0][0] = in[0][0];

View File

@ -101,8 +101,8 @@ typedef struct physic_exp_s
void (*PlayerMove)( pmove_t *pmove, bool clientmove );
// simple objects
physbody_t *(*CreateBody)( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform, int solid );
physbody_t *(*CreatePlayer)( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transform );
physbody_t *(*CreateBody)( sv_edict_t *ed, cmodel_t *mod, const vec3_t origin, const matrix3x3 matrix, int solid );
physbody_t *(*CreatePlayer)( sv_edict_t *ed, cmodel_t *mod, const vec3_t origin, const matrix3x3 matrix );
void (*SetOrigin)( physbody_t *body, vec3_t origin );
void (*SetParameters)( physbody_t *body, cmodel_t *mod, int material, float mass );
@ -119,7 +119,7 @@ typedef struct physic_imp_s
size_t api_size; // must matched with sizeof(physic_imp_t)
void (*ClientMove)( sv_edict_t *ed );
void (*Transform)( sv_edict_t *ed, matrix4x3 transform );
void (*Transform)( sv_edict_t *ed, const vec3_t org, const matrix3x3 matrix );
void (*PlaySound)( sv_edict_t *ed, float volume, const char *sample );
float *(*GetModelVerts)( sv_edict_t *ent, int *numvertices );
} physic_imp_t;

View File

@ -23,6 +23,19 @@ typedef struct vrect_s
int height;
} vrect_t;
typedef struct
{
vec3_t point;
vec4_t modulate;
vec2_t st;
} polyVert_t;
typedef struct
{
int firstVert;
int numVerts;
} decalFragment_t;
typedef struct
{
vrect_t rect; // screen rectangle
@ -60,6 +73,7 @@ typedef struct render_exp_s
bool (*AddRefEntity)( entity_state_t *s1, entity_state_t *s2, float lerp );
bool (*AddDynLight)( vec3_t org, vec3_t color, float intensity );
bool (*AddParticle)( shader_t shader, const vec3_t p1, const vec3_t p2, float rad, float len, float rot, int col );
bool (*AddPolygon)( shader_t shader, int numVerts, const polyVert_t *verts );
bool (*AddLightStyle)( int stylenum, vec3_t color );
void (*ClearScene)( void );
@ -75,7 +89,7 @@ typedef struct render_exp_s
void (*DrawFill)( float x, float y, float w, float h );
void (*DrawStretchRaw)( int x, int y, int w, int h, int cols, int rows, byte *data, bool redraw );
void (*DrawStretchPic)( float x, float y, float w, float h, float s1, float t1, float s2, float t2, shader_t shader );
void (*ImpactMark)( vec3_t org, vec3_t dir, float rot, float radius, vec4_t mod, bool fade, shader_t s, bool tmp );
void (*DrawGetPicSize)( int *w, int *h, shader_t shader );
} render_exp_t;
@ -88,6 +102,7 @@ typedef struct render_imp_s
// client fundamental callbacks
void (*UpdateScreen)( void ); // update screen while loading
void (*StudioEvent)( dstudioevent_t *event, entity_state_t *ent );
void (*AddDecal)( vec3_t org, matrix3x3 m, shader_t s, vec4_t rgba, bool fade, decalFragment_t *df, const vec3_t *v );
void (*ShowCollision)( cmdraw_t callback ); // debug
long (*WndProc)( void *hWnd, uint uMsg, uint wParam, long lParam );
entity_state_t *(*GetClientEdict)( int index );

View File

@ -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 qctest
quake.exe -game tmpQuArK -dev 3 -log +map phystest
:done

View File

@ -375,6 +375,7 @@ void GL_InitCommands( void )
r_nobind = Cvar_Get( "r_nobind", "0", CVAR_CHEAT, "disable all textures (perfomance test)" );
r_drawparticles = Cvar_Get( "r_drawparticles", "1", CVAR_CHEAT, "disable particles (perfomance test)" );
r_drawpolys = Cvar_Get( "r_drawpolys", "1", CVAR_CHEAT, "disable decal polygons (perfomance test)" );
r_frontbuffer = Cvar_Get("r_frontBuffer", "0", CVAR_CHEAT, "directly draw into front buffer (perfomance test)" );
r_showcluster = Cvar_Get("r_showcluster", "0", CVAR_CHEAT, "print info about current viewcluster" );
r_shownormals = Cvar_Get("r_showNormals", "0", CVAR_CHEAT, "draw model normals" );

View File

@ -1738,7 +1738,7 @@ void RB_RenderMeshes( mesh_t *meshes, int numMeshes )
R_DrawParticle();
break;
case MESH_POLY:
// R_DrawPoly();
R_DrawPoly();
break;
default:
Host_Error( "RB_RenderMeshes: bad meshType (%i)\n", m_pRenderMesh->meshType );

319
render/r_fragment.c Normal file
View File

@ -0,0 +1,319 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// r_fragment.c - fragment clipping
//=======================================================================
#include "r_local.h"
#include "mathlib.h"
#define MAX_FRAGMENT_VERTS 128
#define MAX_DECAL_FRAGMENTS 128
#define MAX_DECAL_VERTS 384
static int r_numFragmentVerts;
static int r_maxFragmentVerts;
static vec3_t *r_fragmentVerts;
static int r_numFragments;
static int r_maxFragments;
static decalFragment_t *r_fragments;
static cplane_t r_fragmentPlanes[6];
static int r_fragmentCount;
/*
=================
R_ClipFragment_r
=================
*/
static void R_ClipFragment_r( int numVerts, vec3_t verts, int stage, decalFragment_t *df )
{
int i, f;
float *v;
bool frontSide;
vec3_t front[MAX_FRAGMENT_VERTS];
float dists[MAX_FRAGMENT_VERTS];
int sides[MAX_FRAGMENT_VERTS];
cplane_t *plane;
float dist;
if( numVerts > MAX_FRAGMENT_VERTS - 2 )
Host_Error( "R_ClipFragment: MAX_FRAGMENT_VERTS limit exceeded\n" );
if( stage == 6 )
{
// fully clipped
if( numVerts > 2 )
{
if( r_numFragmentVerts + numVerts > r_maxFragmentVerts )
return;
df->firstVert = r_numFragmentVerts;
df->numVerts = numVerts;
for( i = 0, v = verts; i < numVerts; i++, v += 3 )
VectorCopy( v, r_fragmentVerts[r_numFragmentVerts+i] );
r_numFragmentVerts += numVerts;
}
return;
}
frontSide = false;
plane = &r_fragmentPlanes[stage];
for( i = 0, v = verts; i < numVerts; i++, v += 3 )
{
if( plane->type < 3 )
dists[i] = dist = v[plane->type] - plane->dist;
else dists[i] = dist = DotProduct( v, plane->normal ) - plane->dist;
if( dist > ON_EPSILON )
{
frontSide = true;
sides[i] = SIDE_FRONT;
}
else if( dist < -ON_EPSILON )
sides[i] = SIDE_BACK;
else sides[i] = SIDE_ON;
}
if( !frontSide ) return; // not clipped
// clip it
dists[i] = dists[0];
sides[i] = sides[0];
VectorCopy( verts, (verts + (i * 3)));
for( i = f = 0, v = verts; i < numVerts; i++, v += 3 )
{
switch( sides[i] )
{
case SIDE_FRONT:
VectorCopy( v, front[f] );
f++;
break;
case SIDE_BACK:
break;
case SIDE_ON:
VectorCopy(v, front[f]);
f++;
break;
}
if( sides[i] == SIDE_ON || sides[i+1] == SIDE_ON || sides[i+1] == sides[i] )
continue;
dist = dists[i] / (dists[i] - dists[i+1]);
front[f][0] = v[0] + (v[3] - v[0]) * dist;
front[f][1] = v[1] + (v[4] - v[1]) * dist;
front[f][2] = v[2] + (v[5] - v[2]) * dist;
f++;
}
// continue
R_ClipFragment_r( f, front[0], stage+1, df );
}
/*
=================
R_ClipFragmentToSurface
=================
*/
static void R_ClipFragmentToSurface( surface_t *surf )
{
decalFragment_t *df;
surfPoly_t *p;
vec3_t verts[MAX_FRAGMENT_VERTS];
int i;
// copy vertex data and clip to each triangle
for( p = surf->poly; p; p = p->next )
{
for( i = 0; i < p->numIndices; i += 3 )
{
df = &r_fragments[r_numFragments];
df->firstVert = df->numVerts = 0;
VectorCopy( p->vertices[p->indices[i+0]].xyz, verts[0] );
VectorCopy( p->vertices[p->indices[i+1]].xyz, verts[1] );
VectorCopy( p->vertices[p->indices[i+2]].xyz, verts[2] );
R_ClipFragment_r( 3, verts[0], 0, df );
if( df->numVerts )
{
r_numFragments++;
if( r_numFragmentVerts == r_maxFragmentVerts || r_numFragments == r_maxFragments )
return; // already reached the limit
}
}
}
}
/*
=================
R_RecursiveFragmentNode
=================
*/
static void R_RecursiveFragmentNode( node_t *node, const vec3_t origin, const vec3_t normal, float radius )
{
int i;
float dist;
cplane_t *plane;
surface_t *surf;
if( node->contents != CONTENTS_NODE )
return;
if( r_numFragmentVerts == r_maxFragmentVerts || r_numFragments == r_maxFragments )
return; // already reached the limit somewhere else
// find which side of the node we are on
plane = node->plane;
if( plane->type < 3 )
dist = origin[plane->type] - plane->dist;
else dist = DotProduct( origin, plane->normal ) - plane->dist;
// go down the appropriate sides
if( dist > radius )
{
R_RecursiveFragmentNode( node->children[0], origin, normal, radius );
return;
}
if( dist < -radius )
{
R_RecursiveFragmentNode( node->children[1], origin, normal, radius );
return;
}
// clip to each surface
surf = r_worldModel->surfaces + node->firstSurface;
for( i = 0; i < node->numSurfaces; i++, surf++ )
{
if( r_numFragmentVerts == r_maxFragmentVerts || r_numFragments == r_maxFragments )
break; // already reached the limit
if( surf->fragmentFrame == r_fragmentCount )
continue; // already checked this surface in another node
surf->fragmentFrame = r_fragmentCount;
if( surf->texInfo->surfaceFlags & (SURF_SKY|SURF_NODRAW|SURF_WARP))
continue; // don't bother clipping
if( surf->texInfo->shader->flags & SHADER_NOFRAGMENTS )
continue; // don't bother clipping
if( !BoundsAndSphereIntersect( surf->mins, surf->maxs, origin, radius ))
continue; // no intersection
if(!( surf->flags & SURF_PLANEBACK ))
{
if( DotProduct( normal, surf->plane->normal ) < 0.5f )
continue; // greater than 60 degrees
}
else
{
if( DotProduct( normal, surf->plane->normal ) > -0.5f)
continue; // greater than 60 degrees
}
// clip to the surface
R_ClipFragmentToSurface( surf );
}
// recurse down the children
R_RecursiveFragmentNode( node->children[0], origin, normal, radius );
R_RecursiveFragmentNode( node->children[1], origin, normal, radius );
}
/*
=================
R_DecalFragments
=================
*/
int R_DecalFragments( const vec3_t origin, const matrix3x3 matrix, float radius, int maxVerts, vec3_t *verts, int maxFragments, decalFragment_t *fragments )
{
int i;
float dot;
if( !r_worldModel ) return 0; // map not loaded
r_fragmentCount++; // for multi-check avoidance
// initialize fragments
r_numFragmentVerts = 0;
r_maxFragmentVerts = maxVerts;
r_fragmentVerts = verts;
r_numFragments = 0;
r_maxFragments = maxFragments;
r_fragments = fragments;
// calculate clipping planes
for( i = 0; i < 3; i++ )
{
dot = DotProduct( origin, matrix[i] );
VectorCopy( matrix[i], r_fragmentPlanes[i*2+0].normal );
r_fragmentPlanes[i*2+0].dist = dot - radius;
PlaneClassify( &r_fragmentPlanes[i*2+0] );
VectorNegate( matrix[i], r_fragmentPlanes[i*2+1].normal );
r_fragmentPlanes[i*2+1].dist = -dot - radius;
PlaneClassify( &r_fragmentPlanes[i*2+1] );
}
// clip against world geometry
R_RecursiveFragmentNode( r_worldModel->nodes, origin, matrix[0], radius );
return r_numFragments;
}
/*
=================
R_ImpactMark
temporary marks will be inmediately passed to the renderer
=================
*/
void R_ImpactMark( vec3_t org, vec3_t dir, float rot, float radius, vec4_t rgba, bool fade, shader_t shader, bool temp )
{
int i, j;
vec3_t delta;
matrix3x3 matrix;
int numFragments;
decalFragment_t decalFragments[MAX_DECAL_FRAGMENTS], *df;
vec3_t decalVerts[MAX_DECAL_VERTS];
polyVert_t verts[MAX_VERTS_ON_POLY];
// find orientation vectors
VectorNormalize2( dir, matrix[0] );
PerpendicularVector( matrix[1], matrix[0] );
RotatePointAroundVector( matrix[2], matrix[0], matrix[1], rot );
CrossProduct( matrix[0], matrix[2], matrix[1] );
// get the clipped decal fragments
numFragments = R_DecalFragments( org, matrix, radius, MAX_DECAL_VERTS, decalVerts, MAX_DECAL_FRAGMENTS, decalFragments );
if( !numFragments ) return;
VectorScale( matrix[1], 0.5 / radius, matrix[1] );
VectorScale( matrix[2], 0.5 / radius, matrix[2] );
for( i = 0, df = decalFragments; i < numFragments; i++, df++ )
{
if( !df->numVerts ) continue;
if( df->numVerts > MAX_VERTS_ON_POLY )
df->numVerts = MAX_VERTS_ON_POLY;
// if it is a temporary decal, pass it to the renderer without storing
if( temp )
{
for( j = 0; j < df->numVerts; j++ )
{
VectorCopy( decalVerts[df->firstVert + j], verts[j].point );
VectorSubtract( verts[j].point, org, delta );
verts[j].st[0] = 0.5 + DotProduct( delta, matrix[1] );
verts[j].st[1] = 0.5 + DotProduct( delta, matrix[2] );
Vector4Copy( rgba, verts[j].modulate );
}
R_AddPolyToScene( shader, df->numVerts, verts );
continue;
}
ri.AddDecal( org, matrix, shader, rgba, fade, df, decalVerts );
}
}

View File

@ -220,13 +220,6 @@ typedef struct surfPoly_s
surfPolyVert_t *vertices;
} surfPoly_t;
typedef struct
{
vec3_t xyz;
vec2_t st;
vec4_t modulate;
} polyVert_t;
typedef struct
{
ref_shader_t *shader;
@ -793,6 +786,8 @@ bool R_CullBox( const vec3_t mins, const vec3_t maxs, int clipFlags );
bool R_CullSphere( const vec3_t origin, float radius, int clipFlags );
void R_RotateForEntity( ref_entity_t *entity );
void R_AddMeshToList( meshType_t meshType, void *mesh, ref_shader_t *shader, ref_entity_t *entity, int infoKey );
bool R_AddPolyToScene( shader_t shader, int numVerts, const polyVert_t *verts );
void R_ImpactMark( vec3_t org, vec3_t dir, float rot, float radius, vec4_t rgba, bool fade, shader_t shader, bool temp );
void R_DrawSprite( void );
void R_DrawBeam( void );
void R_DrawParticle( void );
@ -811,6 +806,7 @@ void R_AddBrushModelToList( ref_entity_t *entity );
void R_AddWorldToList( void );
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
void PerpendicularVector( vec3_t dst, const vec3_t src );
// exported funcs
void R_BeginRegistration( const char *map );

View File

@ -552,6 +552,58 @@ static void R_AddParticlesToList( void )
}
}
/*
=================
R_DrawPoly
=================
*/
void R_DrawPoly( void )
{
poly_t *poly = m_pRenderMesh->mesh;
polyVert_t *vert;
int i;
RB_CheckMeshOverflow((poly->numVerts - 2) * 3, poly->numVerts );
for( i = 2; i < poly->numVerts; i++ )
{
ref.indexArray[ref.numIndex++] = ref.numVertex + 0;
ref.indexArray[ref.numIndex++] = ref.numVertex + i-1;
ref.indexArray[ref.numIndex++] = ref.numVertex + i;
}
for( i = 0, vert = poly->verts; i < poly->numVerts; i++, vert++ )
{
ref.vertexArray[ref.numVertex][0] = vert->point[0];
ref.vertexArray[ref.numVertex][1] = vert->point[1];
ref.vertexArray[ref.numVertex][2] = vert->point[2];
ref.inTexCoordArray[ref.numVertex][0] = vert->st[0];
ref.inTexCoordArray[ref.numVertex][1] = vert->st[1];
ref.colorArray[ref.numVertex][0] = vert->modulate[0];
ref.colorArray[ref.numVertex][1] = vert->modulate[1];
ref.colorArray[ref.numVertex][2] = vert->modulate[2];
ref.colorArray[ref.numVertex][3] = vert->modulate[3];
ref.numVertex++;
}
}
/*
=================
R_AddPolysToList
=================
*/
static void R_AddPolysToList( void )
{
poly_t *poly;
int i;
if( !r_drawpolys->integer || !r_numPolys )
return;
r_stats.numPolys += r_numPolys;
for( i = 0, poly = r_polys; i < r_numPolys; i++, poly++ )
R_AddMeshToList( MESH_POLY, poly, poly->shader, r_worldEntity, 0 );
}
// =====================================================================
@ -833,6 +885,7 @@ void R_RenderView( const refdef_t *fd )
R_AddWorldToList();
R_AddEntitiesToList();
R_AddParticlesToList();
R_AddPolysToList();
// sort mesh lists
R_QSortMeshes( r_solidMeshes, r_numSolidMeshes );
@ -1147,6 +1200,28 @@ static bool R_AddLightStyle( int style, vec3_t color )
return true;
}
/*
=================
R_AddPolyToScene
=================
*/
bool R_AddPolyToScene( shader_t shader, int numVerts, const polyVert_t *verts )
{
poly_t *poly;
if( r_numPolys >= MAX_POLYS || r_numPolyVerts + numVerts > MAX_POLY_VERTS )
return false;
poly = &r_polys[r_numPolys++];
poly->shader = r_shaders + shader;
poly->numVerts = numVerts;
poly->verts = &r_polyVerts[r_numPolyVerts];
Mem_Copy( poly->verts, verts, numVerts * sizeof( polyVert_t ));
r_numPolyVerts += numVerts;
return true;
}
/*
=================
R_RenderFrame
@ -1372,6 +1447,7 @@ render_exp_t DLLEXPORT *CreateAPI(stdlib_api_t *input, render_imp_t *engfuncs )
re.AddRefEntity = R_AddEntityToScene;
re.AddDynLight = R_AddDynamicLight;
re.AddParticle = R_AddParticleToScene;
re.AddPolygon = R_AddPolyToScene;
re.ClearScene = R_ClearScene;
re.BeginFrame = R_BeginFrame;
@ -1385,6 +1461,7 @@ render_exp_t DLLEXPORT *CreateAPI(stdlib_api_t *input, render_imp_t *engfuncs )
re.DrawFill = R_DrawFill;
re.DrawStretchRaw = R_DrawStretchRaw;
re.DrawStretchPic = R_DrawStretchPic;
re.ImpactMark = R_ImpactMark;
// get rid of this
re.DrawGetPicSize = R_GetPicSize;

View File

@ -1797,6 +1797,8 @@ static bool R_ParseStageMap( ref_shader_t *shader, shaderStage_t *stage, script_
bundle->textures[bundle->numTextures++] = r_whiteTexture;
else if( !com.stricmp( tok.string, "$blackImage"))
bundle->textures[bundle->numTextures++] = r_blackTexture;
else if( !com.stricmp( tok.string, "$particle"))
bundle->textures[bundle->numTextures++] = r_particleTexture;
else
{
while( 1 )
@ -4062,8 +4064,9 @@ static ref_shader_t *R_CreateDefaultShader( const char *name, int shaderType, ui
shader->stages[0]->bundles[0]->textures[0] = r_defaultConchars;
}
shader->stages[0]->rgbGen.type = RGBGEN_VERTEX;
shader->stages[0]->alphaGen.type = ALPHAGEN_VERTEX;
shader->stages[0]->bundles[0]->numTextures++;
shader->stages[0]->flags |= SHADERSTAGE_BLENDFUNC|SHADERSTAGE_RGBGEN;
shader->stages[0]->flags |= (SHADERSTAGE_BLENDFUNC|SHADERSTAGE_RGBGEN|SHADERSTAGE_ALPHAGEN);
shader->stages[0]->blendFunc.src = GL_SRC_ALPHA;
shader->stages[0]->blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
shader->stages[0]->numBundles++;

View File

@ -64,6 +64,61 @@ void MatrixGL_MultiplyFast (const gl_matrix m1, const gl_matrix m2, gl_matrix ou
out[15] = 1.0;
}
/*
====================
PerpendicularVector
assumes "src" is normalized
====================
*/
void PerpendicularVector( vec3_t dst, const vec3_t src )
{
int pos;
float minelem;
if( src[0] )
{
dst[0] = 0;
if( src[1] )
{
dst[1] = 0;
if( src[2] )
{
dst[2] = 0;
pos = 0;
minelem = fabs( src[0] );
if( fabs( src[1] ) < minelem )
{
pos = 1;
minelem = fabs( src[1] );
}
if( fabs( src[2] ) < minelem )
pos = 2;
dst[pos] = 1;
dst[0] -= src[pos] * src[0];
dst[1] -= src[pos] * src[1];
dst[2] -= src[pos] * src[2];
// normalize the result
VectorNormalize( dst );
}
else dst[2] = 1;
}
else
{
dst[1] = 1;
dst[2] = 0;
}
}
else
{
dst[0] = 1;
dst[1] = 0;
dst[2] = 0;
}
}
/*
====================
RotatePointAroundVector

View File

@ -134,6 +134,10 @@ SOURCE=.\r_draw.c
# End Source File
# Begin Source File
SOURCE=.\r_fragment.c
# End Source File
# Begin Source File
SOURCE=.\r_image.c
# End Source File
# Begin Source File

View File

@ -18,7 +18,8 @@ fopen
Beta 13.12.08
0. move effects to client.dat
0. move effects to client.dat OK
1. fixangle
0. light_environment
1. научить оружие стрелять

View File

@ -162,7 +162,7 @@ opcode_t pr_opcodes[] =
{"<RETURN>", "RETURN", -1, ASSOC_LEFT, &type_float, &type_void, &type_void},
{"!", "NOT_F", -1, ASSOC_LEFT, &type_float, &type_void, &type_float},
{"!", "NOT_V", -1, ASSOC_LEFT, &type_vector, &type_void, &type_float},
{"!", "NOT_S", -1, ASSOC_LEFT, &type_vector, &type_void, &type_float},
{"!", "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},
{"<IF>", "IF", -1, ASSOC_RIGHT,&type_float, NULL, &type_void},

View File

@ -502,7 +502,7 @@ word PR_WriteProgdefs( void )
switch( crc )
{
case 16873:
case 3519:
PR_Message("Xash3D unmodified server.dat\n");
if(!com.strcmp(progsoutname, "unknown.dat")) com.strcpy(progsoutname, "server.dat");
break;