03 Aug 2008
This commit is contained in:
parent
8e0617c350
commit
c55dc2f0a9
|
@ -20,12 +20,29 @@ void CL_SetFont_f( void )
|
|||
{
|
||||
if(Cmd_Argc() < 2)
|
||||
{
|
||||
Msg("Usage: setfont <fontname>\n");
|
||||
Msg( "Usage: setfont <fontname>\n" );
|
||||
return;
|
||||
}
|
||||
Cvar_Set("cl_font", Cmd_Argv(1));
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_Download_f
|
||||
|
||||
Request a download from the server
|
||||
===============
|
||||
*/
|
||||
void CL_Download_f( void )
|
||||
{
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "Usage: download <filename>\n" );
|
||||
return;
|
||||
}
|
||||
CL_CheckOrDownloadFile(Cmd_Argv(1));
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_ScreenshotGetName
|
||||
|
|
|
@ -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_ents.c -- entity parsing and management
|
||||
//=======================================================================
|
||||
// Copyright XashXT Group 2008 ©
|
||||
// cl_frame.c - client world snapshot
|
||||
//=======================================================================
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
|
@ -29,22 +13,13 @@ FRAME PARSING
|
|||
|
||||
=========================================================================
|
||||
*/
|
||||
|
||||
float LerpAngle (float a2, float a1, float frac)
|
||||
void CL_UpdateEntityFileds( edict_t *ent )
|
||||
{
|
||||
if (a1 - a2 > 180) a1 -= 360;
|
||||
if (a1 - a2 < -180) a1 += 360;
|
||||
return a2 + frac * (a1 - a2);
|
||||
}
|
||||
|
||||
float LerpView(float org1, float org2, float ofs1, float ofs2, float frac)
|
||||
{
|
||||
return org1 + ofs1 + frac * (org2 + ofs2 - (org1 + ofs1));
|
||||
}
|
||||
|
||||
float LerpPoint( float oldpoint, float curpoint, float frac )
|
||||
{
|
||||
return oldpoint + frac * (curpoint - oldpoint);
|
||||
// copy state to progs
|
||||
ent->progs.cl->classname = cl.edict_classnames[ent->priv.cl->current.classname];
|
||||
ent->progs.cl->modelindex = ent->priv.cl->current.model.index;
|
||||
ent->progs.cl->soundindex = ent->priv.cl->current.soundindex;
|
||||
ent->progs.cl->model = PRVM_SetEngineString( cl.configstrings[CS_MODELS+ent->priv.cl->current.model.index] );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -98,6 +73,9 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
|
|||
|
||||
ent->priv.cl->serverframe = cl.frame.serverframe;
|
||||
ent->priv.cl->current = *state;
|
||||
|
||||
// update prvm fields
|
||||
CL_UpdateEntityFileds( ent );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -214,9 +192,9 @@ CL_ParseFrame
|
|||
*/
|
||||
void CL_ParseFrame( sizebuf_t *msg )
|
||||
{
|
||||
int cmd;
|
||||
int len;
|
||||
frame_t *old;
|
||||
int cmd, len;
|
||||
edict_t *clent;
|
||||
frame_t *old;
|
||||
|
||||
memset( &cl.frame, 0, sizeof(cl.frame));
|
||||
cl.frame.serverframe = MSG_ReadLong( msg );
|
||||
|
@ -264,21 +242,24 @@ void CL_ParseFrame( sizebuf_t *msg )
|
|||
len = MSG_ReadByte( msg );
|
||||
MSG_ReadData( msg, &cl.frame.areabits, len );
|
||||
|
||||
// read playerinfo
|
||||
// read clientinfex
|
||||
cmd = MSG_ReadByte( msg );
|
||||
if( cmd != svc_playerinfo ) Host_Error( "CL_ParseFrame: not playerinfo\n" );
|
||||
if( old ) MSG_ReadDeltaPlayerstate( msg, &old->ps, &cl.frame.ps );
|
||||
else MSG_ReadDeltaPlayerstate( msg, NULL, &cl.frame.ps );
|
||||
|
||||
// HACKHACK
|
||||
if( cls.state == ca_cinematic || cls.demoplayback )
|
||||
cl.frame.ps.pm_type = PM_FREEZE; // demo or movie playback
|
||||
if( cmd != svc_clientindex ) Host_Error( "CL_ParseFrame: not clientindex\n" );
|
||||
clent = PRVM_EDICT_NUM( MSG_ReadByte( msg )); // get client
|
||||
|
||||
// read packet entities
|
||||
cmd = MSG_ReadByte( msg );
|
||||
if( cmd != svc_packetentities ) Host_Error("CL_ParseFrame: not packetentities[%d]\n", cmd );
|
||||
CL_ParsePacketEntities( msg, old, &cl.frame );
|
||||
|
||||
// now we can reading delta player state
|
||||
if( old ) cl.frame.ps = MSG_ParseDeltaPlayer( &old->ps, &clent->priv.cl->current );
|
||||
else cl.frame.ps = MSG_ParseDeltaPlayer( NULL, &clent->priv.cl->current );
|
||||
|
||||
// HACKHACK
|
||||
if( cls.state == ca_cinematic || cls.demoplayback )
|
||||
cl.frame.ps.pm_type = PM_FREEZE; // demo or movie playback
|
||||
|
||||
// save the frame off in the backup array for later delta comparisons
|
||||
cl.frames[cl.frame.serverframe & UPDATE_MASK] = cl.frame;
|
||||
|
||||
|
@ -311,101 +292,15 @@ CL_AddPacketEntities
|
|||
*/
|
||||
void CL_AddPacketEntities( frame_t *frame )
|
||||
{
|
||||
entity_t refent;
|
||||
entity_state_t *s1;
|
||||
float autorotate;
|
||||
int i, pnum;
|
||||
edict_t *ent;
|
||||
int autoanim;
|
||||
uint effects, renderfx;
|
||||
|
||||
// bonus items rotate at a fixed rate
|
||||
autorotate = anglemod( cl.time / 10 );
|
||||
|
||||
// brush models can auto animate their frames
|
||||
autoanim = 2 * cl.time / 1000;
|
||||
|
||||
memset( &refent, 0, sizeof(refent));
|
||||
int pnum;
|
||||
|
||||
for( pnum = 0; pnum < frame->num_entities; pnum++ )
|
||||
{
|
||||
s1 = &cl_parse_entities[(frame->parse_entities+pnum)&(MAX_PARSE_ENTITIES-1)];
|
||||
|
||||
s1 = &cl_parse_entities[(frame->parse_entities + pnum)&(MAX_PARSE_ENTITIES-1)];
|
||||
ent = PRVM_EDICT_NUM( s1->number );
|
||||
|
||||
effects = s1->effects;
|
||||
renderfx = s1->renderfx;
|
||||
refent.frame = s1->model.frame;
|
||||
|
||||
// copy state to progs
|
||||
ent->progs.cl->modelindex = ent->priv.cl->current.model.index;
|
||||
ent->progs.cl->soundindex = ent->priv.cl->current.soundindex;
|
||||
//ent->progs.cl->model = PRVM_SetEngineString( cl.configstrings[CS_MODELS+ent->priv.cl->current.model.index] );
|
||||
|
||||
// copy state to render
|
||||
refent.prev.frame = ent->priv.cl->prev.model.frame;
|
||||
refent.backlerp = 1.0f - cl.lerpfrac;
|
||||
refent.alpha = s1->renderamt;
|
||||
refent.body = s1->model.body;
|
||||
refent.sequence = s1->model.sequence;
|
||||
refent.animtime = s1->model.animtime;
|
||||
|
||||
// setup latchedvars
|
||||
refent.prev.animtime = ent->priv.cl->prev.model.animtime;
|
||||
VectorCopy( ent->priv.cl->prev.origin, refent.prev.origin );
|
||||
VectorCopy( ent->priv.cl->prev.angles, refent.prev.angles );
|
||||
refent.prev.sequence = ent->priv.cl->prev.model.sequence;
|
||||
refent.prev.frame = ent->priv.cl->prev.model.frame;
|
||||
//refent.prev.sequencetime;
|
||||
|
||||
// interpolate origin
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
refent.origin[i] = LerpPoint( ent->priv.cl->prev.origin[i], ent->priv.cl->current.origin[i], cl.lerpfrac );
|
||||
refent.oldorigin[i] = refent.origin[i];
|
||||
}
|
||||
|
||||
// set skin
|
||||
refent.skin = s1->model.skin;
|
||||
refent.model = cl.model_draw[s1->model.index];
|
||||
refent.weaponmodel = cl.model_draw[s1->pmodel.index];
|
||||
refent.flags = renderfx;//FIXME: it's wrong!!!
|
||||
|
||||
// calculate angles
|
||||
if( effects & EF_ROTATE )
|
||||
{
|
||||
// some bonus items auto-rotate
|
||||
refent.angles[0] = 0;
|
||||
refent.angles[1] = autorotate;
|
||||
refent.angles[2] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// interpolate angles
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
refent.angles[i] = LerpAngle( ent->priv.cl->prev.angles[i], ent->priv.cl->current.angles[i], cl.lerpfrac );
|
||||
}
|
||||
}
|
||||
|
||||
if( s1->number == cl.playernum + 1 )
|
||||
{
|
||||
refent.flags |= RF_PLAYERMODEL; // only draw from mirrors
|
||||
|
||||
// just only for test
|
||||
refent.controller[0] = 90.0;
|
||||
refent.controller[1] = 90.0;
|
||||
refent.controller[2] = 180.0;
|
||||
refent.controller[3] = 180.0;
|
||||
refent.sequence = 0;
|
||||
refent.frame = 0;
|
||||
}
|
||||
|
||||
// if set to invisible, skip
|
||||
if( !s1->model.index ) continue;
|
||||
|
||||
// add to refresh list
|
||||
V_AddEntity( &refent );
|
||||
re->AddRefEntity( &cl.refdef, &ent->priv.cl->current, &ent->priv.cl->prev, cl.lerpfrac );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,38 +311,22 @@ void CL_AddPacketEntities( frame_t *frame )
|
|||
CL_AddViewWeapon
|
||||
==============
|
||||
*/
|
||||
void CL_AddViewWeapon( entity_state_t *ps, entity_state_t *ops )
|
||||
void CL_AddViewWeapon( entity_state_t *ps )
|
||||
{
|
||||
entity_t gun; // view model
|
||||
edict_t *view; // view model
|
||||
|
||||
// allow the gun to be completely removed
|
||||
if( !cl_gun->value ) return;
|
||||
|
||||
// don't draw gun if in wide angle view
|
||||
if (ps->fov > 135) return;
|
||||
if( ps->fov > 135 ) return;
|
||||
|
||||
memset (&gun, 0, sizeof(gun));
|
||||
|
||||
if (gun_model) gun.model = gun_model; // development tool
|
||||
else gun.model = cl.model_draw[ps->vmodel.index];
|
||||
if (!gun.model) return;
|
||||
|
||||
// set up gun position
|
||||
VectorCopy( cl.refdef.vieworg, gun.origin );
|
||||
VectorCopy( cl.refdef.viewangles, gun.angles );
|
||||
|
||||
gun.frame = ps->vmodel.frame;
|
||||
if( gun.frame == 0 ) gun.prev.frame = 0; // just changed weapons, don't lerp from old
|
||||
else gun.prev.frame = ops->vmodel.frame;
|
||||
|
||||
gun.body = ps->vmodel.body;
|
||||
gun.skin = ps->vmodel.skin;
|
||||
gun.sequence = ps->vmodel.sequence;
|
||||
|
||||
gun.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_VIEWMODEL;
|
||||
gun.backlerp = 1.0 - cl.lerpfrac;
|
||||
VectorCopy ( gun.origin, gun.oldorigin ); // don't lerp at all
|
||||
V_AddEntity( &gun );
|
||||
view = PRVM_EDICT_NUM( ps->aiment );
|
||||
VectorCopy( cl.refdef.vieworg, view->priv.cl->current.origin );
|
||||
VectorCopy( cl.refdef.viewangles, view->priv.cl->current.angles );
|
||||
VectorCopy( cl.refdef.vieworg, view->priv.cl->prev.origin );
|
||||
VectorCopy( cl.refdef.viewangles, view->priv.cl->prev.angles );
|
||||
re->AddRefEntity( &cl.refdef, &view->priv.cl->current, &view->priv.cl->prev, cl.lerpfrac );
|
||||
}
|
||||
|
||||
|
||||
|
@ -539,11 +418,8 @@ void CL_CalcViewValues( void )
|
|||
// interpolate field of view
|
||||
cl.refdef.fov_x = ops->fov + lerp * ( ps->fov - ops->fov );
|
||||
|
||||
// don't interpolate blend color
|
||||
Vector4Set( cl.refdef.blend, 0, 0, 0, 0 ); // FIXME: calculate blend on client-side
|
||||
|
||||
// add the weapon
|
||||
CL_AddViewWeapon( ps, ops );
|
||||
CL_AddViewWeapon( ps );
|
||||
}
|
||||
|
||||
/*
|
|
@ -84,7 +84,7 @@ void CL_SetLightstyle( int i )
|
|||
char *s;
|
||||
int j, k;
|
||||
|
||||
s = cl.configstrings[i+CS_LIGHTS];
|
||||
s = cl.configstrings[i+CS_LIGHTSTYLES];
|
||||
j = com.strlen( s );
|
||||
if( j >= MAX_STRING ) Host_Error("CL_SetLightStyle: lightstyle %s is too long\n", s );
|
||||
|
||||
|
@ -104,8 +104,8 @@ void CL_AddLightStyles (void)
|
|||
int i;
|
||||
clightstyle_t *ls;
|
||||
|
||||
for (i=0,ls=cl_lightstyle ; i<MAX_LIGHTSTYLES ; i++, ls++)
|
||||
V_AddLightStyle (i, ls->value[0], ls->value[1], ls->value[2]);
|
||||
for( i = 0, ls = cl_lightstyle; i < MAX_LIGHTSTYLES; i++, ls++ )
|
||||
re->AddLightStyle( &cl.refdef, i, ls->value );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -226,15 +226,14 @@ CL_AddDLights
|
|||
*/
|
||||
void CL_AddDLights (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;
|
||||
V_AddLight (dl->origin, dl->radius, dl->color[0], dl->color[1], dl->color[2]);
|
||||
if( dl->radius )
|
||||
re->AddDynLight( &cl.refdef, dl->origin, dl->color, dl->radius );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -399,27 +398,25 @@ void CL_AddParticles (void)
|
|||
}
|
||||
|
||||
p->next = NULL;
|
||||
if (!tail)
|
||||
active = tail = p;
|
||||
if( !tail ) active = tail = p;
|
||||
else
|
||||
{
|
||||
tail->next = p;
|
||||
tail = p;
|
||||
}
|
||||
|
||||
if (alpha > 1.0)
|
||||
alpha = 1;
|
||||
if( alpha > 1.0 ) alpha = 1;
|
||||
color = p->color;
|
||||
|
||||
time2 = time*time;
|
||||
|
||||
org[0] = p->org[0] + p->vel[0]*time + p->accel[0]*time2;
|
||||
org[1] = p->org[1] + p->vel[1]*time + p->accel[1]*time2;
|
||||
org[2] = p->org[2] + p->vel[2]*time + p->accel[2]*time2;
|
||||
org[0] = p->org[0] + p->vel[0] * time + p->accel[0] * time2;
|
||||
org[1] = p->org[1] + p->vel[1] * time + p->accel[1] * time2;
|
||||
org[2] = p->org[2] + p->vel[2] * time + p->accel[2] * time2;
|
||||
|
||||
V_AddParticle (org, color, alpha);
|
||||
re->AddParticle( &cl.refdef, org, alpha, color );
|
||||
// PMM
|
||||
if (p->alphavel == INSTANT_PARTICLE)
|
||||
if( p->alphavel == INSTANT_PARTICLE )
|
||||
{
|
||||
p->alphavel = 0.0;
|
||||
p->alpha = 0.0;
|
||||
|
|
|
@ -334,7 +334,8 @@ void CL_ClearState (void)
|
|||
CL_FreeEdicts();
|
||||
|
||||
// wipe the entire cl structure
|
||||
memset (&cl, 0, sizeof(cl));
|
||||
Mem_FreePool( &cl.refdef.mempool );
|
||||
memset( &cl, 0, sizeof(cl));
|
||||
MSG_Clear( &cls.netchan.message );
|
||||
}
|
||||
|
||||
|
@ -859,187 +860,64 @@ CL_Userinfo_f
|
|||
*/
|
||||
void CL_Userinfo_f (void)
|
||||
{
|
||||
Msg ("User info settings:\n");
|
||||
Info_Print (Cvar_Userinfo());
|
||||
Msg( "User info settings:" );
|
||||
Info_Print( Cvar_Userinfo());
|
||||
}
|
||||
|
||||
int precache_check; // for autodownload of precache items
|
||||
int precache_spawncount;
|
||||
int precache_tex;
|
||||
int precache_model_skin;
|
||||
|
||||
byte *precache_model; // used for skin checking in alias models
|
||||
|
||||
#define PLAYER_MULT 5
|
||||
|
||||
// ENV_CNT is map load, ENV_CNT+1 is first env map
|
||||
#define ENV_CNT (CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT)
|
||||
#define TEXTURE_CNT (ENV_CNT+13)
|
||||
// ENV_CNT is map load, ENV_CNT+1 is first cubemap
|
||||
#define ENV_CNT MAX_CONFIGSTRINGS
|
||||
#define TEXTURE_CNT (ENV_CNT+13)
|
||||
|
||||
static const char *env_suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
|
||||
|
||||
void CL_RequestNextDownload (void)
|
||||
void CL_RequestNextDownload( void )
|
||||
{
|
||||
uint map_checksum; // for detecting cheater maps
|
||||
string fn;
|
||||
studiohdr_t *pheader;
|
||||
uint map_checksum; // for detecting cheater maps
|
||||
|
||||
if(cls.state != ca_connected)
|
||||
if( cls.state != ca_connected )
|
||||
return;
|
||||
|
||||
if (!allow_download->value && precache_check < ENV_CNT)
|
||||
if( !allow_download->value && precache_check < ENV_CNT )
|
||||
precache_check = ENV_CNT;
|
||||
|
||||
//ZOID
|
||||
if (precache_check == CS_MODELS)
|
||||
if( precache_check == CS_MODELS )
|
||||
{
|
||||
// confirm map
|
||||
precache_check = CS_MODELS+2; // 0 isn't used
|
||||
if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS+1]))
|
||||
return; // started a download
|
||||
if(!CL_CheckOrDownloadFile( cl.configstrings[CS_MODELS+1] ))
|
||||
return; // started a download map
|
||||
}
|
||||
if (precache_check >= CS_MODELS && precache_check < CS_MODELS+MAX_MODELS)
|
||||
if( precache_check >= CS_MODELS && precache_check < CS_MODELS+MAX_MODELS )
|
||||
{
|
||||
while (precache_check < CS_MODELS+MAX_MODELS && cl.configstrings[precache_check][0])
|
||||
while( precache_check < CS_MODELS+MAX_MODELS && cl.configstrings[precache_check][0])
|
||||
{
|
||||
if (cl.configstrings[precache_check][0] == '*' || cl.configstrings[precache_check][0] == '#')
|
||||
{
|
||||
precache_check++;
|
||||
continue;
|
||||
}
|
||||
if (precache_model_skin == 0)
|
||||
{
|
||||
if (!CL_CheckOrDownloadFile(cl.configstrings[precache_check])) {
|
||||
precache_model_skin = 1;
|
||||
return; // started a download
|
||||
}
|
||||
precache_model_skin = 1;
|
||||
}
|
||||
|
||||
// checking for skins in the model
|
||||
if (!precache_model)
|
||||
{
|
||||
precache_model = FS_LoadFile (cl.configstrings[precache_check], NULL);
|
||||
if (!precache_model)
|
||||
{
|
||||
precache_model_skin = 0;
|
||||
precache_check++;
|
||||
continue; // couldn't load it
|
||||
}
|
||||
if (LittleLong(*(uint *)precache_model) != IDSTUDIOHEADER)
|
||||
{
|
||||
// not an studio model
|
||||
precache_model = 0;
|
||||
precache_model_skin = 0;
|
||||
precache_check++;
|
||||
continue;
|
||||
}
|
||||
pheader = (studiohdr_t *)precache_model;
|
||||
if (LittleLong (pheader->version) != STUDIO_VERSION)
|
||||
{
|
||||
precache_check++;
|
||||
precache_model_skin = 0;
|
||||
continue; // couldn't load it
|
||||
}
|
||||
}
|
||||
|
||||
pheader = (studiohdr_t *)precache_model;
|
||||
|
||||
if (precache_model)
|
||||
{
|
||||
precache_model = 0;
|
||||
}
|
||||
precache_model_skin = 0;
|
||||
precache_check++;
|
||||
com.sprintf( fn, "%s", cl.configstrings[precache_check++]);
|
||||
if(!CL_CheckOrDownloadFile( fn )) return; // started a download
|
||||
}
|
||||
precache_check = CS_SOUNDS;
|
||||
}
|
||||
if (precache_check >= CS_SOUNDS && precache_check < CS_SOUNDS+MAX_SOUNDS)
|
||||
if( precache_check >= CS_SOUNDS && precache_check < CS_SOUNDS+MAX_SOUNDS )
|
||||
{
|
||||
if (precache_check == CS_SOUNDS) precache_check++; // zero is blank
|
||||
while (precache_check < CS_SOUNDS+MAX_SOUNDS && cl.configstrings[precache_check][0])
|
||||
if( precache_check == CS_SOUNDS ) precache_check++; // zero is blank
|
||||
while( precache_check < CS_SOUNDS+MAX_SOUNDS && cl.configstrings[precache_check][0])
|
||||
{
|
||||
if (cl.configstrings[precache_check][0] == '*')
|
||||
// sound pathes from model events
|
||||
if( cl.configstrings[precache_check][0] == '*' )
|
||||
{
|
||||
precache_check++;
|
||||
continue;
|
||||
}
|
||||
com.sprintf(fn, "sound/%s", cl.configstrings[precache_check++]);
|
||||
if (!CL_CheckOrDownloadFile(fn)) return; // started a download
|
||||
com.sprintf( fn, "sound/%s", cl.configstrings[precache_check++]);
|
||||
if(!CL_CheckOrDownloadFile( fn )) return; // started a download
|
||||
}
|
||||
precache_check = CS_IMAGES;
|
||||
}
|
||||
if (precache_check >= CS_IMAGES && precache_check < CS_IMAGES+MAX_IMAGES)
|
||||
{
|
||||
if (precache_check == CS_IMAGES) precache_check++; // zero is blank
|
||||
while (precache_check < CS_IMAGES+MAX_IMAGES && cl.configstrings[precache_check][0])
|
||||
{
|
||||
com.sprintf(fn, "pics/%s.pcx", cl.configstrings[precache_check++]);
|
||||
if (!CL_CheckOrDownloadFile(fn)) return; // started a download
|
||||
}
|
||||
precache_check = CS_PLAYERSKINS;
|
||||
}
|
||||
// skins are special, since a player has three things to download:
|
||||
// model, weapon model and skin
|
||||
// so precache_check is now *3
|
||||
if (precache_check >= CS_PLAYERSKINS && precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT)
|
||||
{
|
||||
while (precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT)
|
||||
{
|
||||
int i, n;
|
||||
char model[MAX_QPATH], skin[MAX_QPATH], *p;
|
||||
|
||||
i = (precache_check - CS_PLAYERSKINS)/PLAYER_MULT;
|
||||
n = (precache_check - CS_PLAYERSKINS)%PLAYER_MULT;
|
||||
|
||||
if (!cl.configstrings[CS_PLAYERSKINS+i][0])
|
||||
{
|
||||
precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((p = com.strchr(cl.configstrings[CS_PLAYERSKINS+i], '\\')) != NULL)
|
||||
p++;
|
||||
else p = cl.configstrings[CS_PLAYERSKINS+i];
|
||||
com.strcpy(model, p);
|
||||
p = com.strchr(model, '/');
|
||||
if (!p) p = com.strchr(model, '\\');
|
||||
if (p)
|
||||
{
|
||||
*p++ = 0;
|
||||
com.strcpy(skin, p);
|
||||
}
|
||||
else *skin = 0;
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case 0: // model
|
||||
com.sprintf(fn, "models/players/%s/player.mdl", model);
|
||||
if (!CL_CheckOrDownloadFile(fn))
|
||||
{
|
||||
precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 1;
|
||||
return; // started a download
|
||||
}
|
||||
n++;
|
||||
/*FALL THROUGH*/
|
||||
case 1: // weapon model
|
||||
com.sprintf(fn, "weapons/%s.mdl", model);
|
||||
if (!CL_CheckOrDownloadFile(fn))
|
||||
{
|
||||
precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 2;
|
||||
return; // started a download
|
||||
}
|
||||
n++;
|
||||
/*FALL THROUGH*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// precache phase completed
|
||||
precache_check = ENV_CNT;
|
||||
}
|
||||
|
||||
if (precache_check == ENV_CNT)
|
||||
if( precache_check == ENV_CNT )
|
||||
{
|
||||
precache_check = ENV_CNT + 1;
|
||||
|
||||
|
@ -1050,52 +928,47 @@ void CL_RequestNextDownload (void)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (precache_check > ENV_CNT && precache_check < TEXTURE_CNT)
|
||||
if( precache_check > ENV_CNT && precache_check < TEXTURE_CNT )
|
||||
{
|
||||
if( allow_download->value )
|
||||
{
|
||||
while (precache_check < TEXTURE_CNT)
|
||||
while( precache_check < TEXTURE_CNT )
|
||||
{
|
||||
int n = precache_check++ - ENV_CNT - 1;
|
||||
|
||||
if (n & 1) com.sprintf(fn, "gfx/env/%s.dds", cl.configstrings[CS_SKY] ); // cubemap pack
|
||||
else com.sprintf(fn, "gfx/env/%s%s.tga", cl.configstrings[CS_SKY], env_suf[n/2]);
|
||||
if (!CL_CheckOrDownloadFile(fn)) return; // started a download
|
||||
if( n & 1 ) com.sprintf( fn, "gfx/env/%s.dds", cl.configstrings[CS_SKYNAME] ); // cubemap pack
|
||||
else com.sprintf( fn, "gfx/env/%s%s.tga", cl.configstrings[CS_SKYNAME], env_suf[n/2] );
|
||||
if(!CL_CheckOrDownloadFile( fn )) return; // started a download
|
||||
}
|
||||
}
|
||||
precache_check = TEXTURE_CNT;
|
||||
}
|
||||
|
||||
if (precache_check == TEXTURE_CNT)
|
||||
if( precache_check == TEXTURE_CNT )
|
||||
{
|
||||
precache_check = TEXTURE_CNT+1;
|
||||
precache_tex = 0;
|
||||
}
|
||||
|
||||
// confirm existance of textures, download any that don't exist
|
||||
if (precache_check == TEXTURE_CNT+1)
|
||||
if( precache_check == TEXTURE_CNT + 1 )
|
||||
{
|
||||
if( allow_download->value )
|
||||
{
|
||||
while( precache_tex < pe->NumTextures())
|
||||
{
|
||||
string fn;
|
||||
|
||||
com.sprintf(fn, "textures/%s.tga", pe->GetTextureName( precache_tex++ ));
|
||||
com.sprintf( fn, "textures/%s.tga", pe->GetTextureName( precache_tex++ ));
|
||||
if(!CL_CheckOrDownloadFile(fn)) return; // started a download
|
||||
}
|
||||
}
|
||||
precache_check = TEXTURE_CNT+999;
|
||||
precache_check = TEXTURE_CNT + 999;
|
||||
}
|
||||
|
||||
//ZOID
|
||||
CL_RegisterSounds();
|
||||
CL_PrepRefresh();
|
||||
|
||||
if( cls.demoplayback ) return; // not really connected
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, va("begin %i\n", precache_spawncount));
|
||||
MSG_Print( &cls.netchan.message, va("begin %i\n", precache_spawncount ));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1106,13 +979,10 @@ The server will send this command right
|
|||
before allowing the client into the server
|
||||
=================
|
||||
*/
|
||||
void CL_Precache_f (void)
|
||||
void CL_Precache_f( void )
|
||||
{
|
||||
precache_check = CS_MODELS;
|
||||
precache_spawncount = com.atoi(Cmd_Argv(1));
|
||||
precache_model = 0;
|
||||
precache_model_skin = 0;
|
||||
|
||||
CL_RequestNextDownload();
|
||||
}
|
||||
|
||||
|
@ -1190,6 +1060,7 @@ void CL_InitLocal (void)
|
|||
Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server" );
|
||||
Cmd_AddCommand ("record", CL_Record_f, "record a demo" );
|
||||
Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "playing a demo" );
|
||||
Cmd_AddCommand ("movie", CL_PlayVideo_f, "playing a movie" );
|
||||
Cmd_AddCommand ("stop", CL_Stop_f, "stop playing or recording a demo" );
|
||||
|
||||
Cmd_AddCommand ("quit", CL_Quit_f, "quit from game" );
|
||||
|
@ -1221,7 +1092,7 @@ CL_WriteConfiguration
|
|||
Writes key bindings and archived cvars to config.cfg
|
||||
===============
|
||||
*/
|
||||
void CL_WriteConfiguration (void)
|
||||
void CL_WriteConfiguration( void )
|
||||
{
|
||||
file_t *f;
|
||||
|
||||
|
@ -1252,66 +1123,6 @@ void CL_WriteConfiguration (void)
|
|||
else MsgDev( D_ERROR, "Couldn't write vars.rc.\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_FixCvarCheats
|
||||
|
||||
==================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
cvar_t *var;
|
||||
} cheatvar_t;
|
||||
|
||||
cheatvar_t cheatvars[] = {
|
||||
{"timescale", "1"},
|
||||
{"r_drawworld", "1"},
|
||||
{"cl_testlights", "0"},
|
||||
{"r_fullbright", "0"},
|
||||
{"r_drawflat", "0"},
|
||||
{"paused", "0"},
|
||||
{"sw_draworder", "0"},
|
||||
{"gl_lightmap", "0"},
|
||||
{"gl_saturatelighting", "0"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
int numcheatvars;
|
||||
|
||||
void CL_FixCvarCheats (void)
|
||||
{
|
||||
int i;
|
||||
cheatvar_t *var;
|
||||
|
||||
if ( !com.strcmp(cl.configstrings[CS_MAXCLIENTS], "1")
|
||||
|| !cl.configstrings[CS_MAXCLIENTS][0] )
|
||||
return; // single player can cheat
|
||||
|
||||
// find all the cvars if we haven't done it yet
|
||||
if (!numcheatvars)
|
||||
{
|
||||
while (cheatvars[numcheatvars].name)
|
||||
{
|
||||
cheatvars[numcheatvars].var = Cvar_Get (cheatvars[numcheatvars].name,
|
||||
cheatvars[numcheatvars].value, 0, "no description" );
|
||||
numcheatvars++;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure they are all set to the proper values
|
||||
for (i=0, var = cheatvars ; i<numcheatvars ; i++, var++)
|
||||
{
|
||||
if ( com.strcmp (var->var->string, var->value) )
|
||||
{
|
||||
Cvar_Set (var->name, var->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
|
@ -1322,9 +1133,6 @@ CL_SendCommand
|
|||
*/
|
||||
void CL_SendCommand (void)
|
||||
{
|
||||
// fix any cheating cvars
|
||||
CL_FixCvarCheats ();
|
||||
|
||||
// send intentions now
|
||||
CL_SendCmd ();
|
||||
|
||||
|
|
|
@ -22,13 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "common.h"
|
||||
#include "client.h"
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void CL_DownloadFileName(char *dest, int destlen, char *fn)
|
||||
{
|
||||
com.strncpy(dest, fn, destlen );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_CheckOrDownloadFile
|
||||
|
@ -37,138 +30,49 @@ Returns true if the file exists, otherwise it attempts
|
|||
to start a download from the server.
|
||||
===============
|
||||
*/
|
||||
bool CL_CheckOrDownloadFile (char *filename)
|
||||
bool CL_CheckOrDownloadFile( const char *filename )
|
||||
{
|
||||
file_t *fp;
|
||||
char name[MAX_SYSPATH];
|
||||
string name;
|
||||
file_t *f;
|
||||
|
||||
if (com.strstr (filename, ".."))
|
||||
{
|
||||
Msg ("Refusing to download a path with ..\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (FS_LoadFile (filename, NULL))
|
||||
if( FS_FileExists( filename ))
|
||||
{
|
||||
// it exists, no need to download
|
||||
return true;
|
||||
}
|
||||
|
||||
com.strcpy (cls.downloadname, filename);
|
||||
com.strcpy (cls.downloadtempname, filename);
|
||||
com.strncpy( cls.downloadname, filename, MAX_STRING );
|
||||
com.strncpy( cls.downloadtempname, filename, MAX_STRING );
|
||||
|
||||
// download to a temp name, and only rename
|
||||
// to the real name when done, so if interrupted
|
||||
// a runt file wont be left
|
||||
FS_StripExtension (cls.downloadtempname);
|
||||
FS_DefaultExtension(cls.downloadtempname, ".tmp");
|
||||
// download to a temp name, and only rename to the real name when done,
|
||||
// so if interrupted a runt file won't be left
|
||||
FS_StripExtension( cls.downloadtempname );
|
||||
FS_DefaultExtension( cls.downloadtempname, ".tmp" );
|
||||
com.strncpy( name, cls.downloadtempname, MAX_STRING );
|
||||
|
||||
//ZOID
|
||||
// check to see if we already have a tmp for this file, if so, try to resume
|
||||
// open the file if not opened yet
|
||||
CL_DownloadFileName(name, sizeof(name), cls.downloadtempname);
|
||||
|
||||
|
||||
fp = FS_Open(name, "r+b");
|
||||
if (fp)
|
||||
f = FS_Open( name, "a+b" );
|
||||
if( f )
|
||||
{
|
||||
// it exists
|
||||
int len;
|
||||
FS_Seek(fp, 0, SEEK_END);
|
||||
len = FS_Tell(fp);
|
||||
|
||||
cls.download = fp;
|
||||
int len = FS_Tell( f );
|
||||
|
||||
cls.download = f;
|
||||
// give the server an offset to start the download
|
||||
Msg ("Resuming %s\n", cls.downloadname);
|
||||
MsgDev( D_INFO, "Resume download %s at %i\n", cls.downloadname, len );
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, va("download %s %i", cls.downloadname, len));
|
||||
MSG_Print( &cls.netchan.message, va("download %s %i", cls.downloadname, len ));
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg ("Downloading %s\n", cls.downloadname);
|
||||
MsgDev( D_INFO, "Start download %s\n", cls.downloadname );
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, va("download %s", cls.downloadname));
|
||||
MSG_Print( &cls.netchan.message, va("download %s", cls.downloadname ));
|
||||
}
|
||||
|
||||
cls.downloadnumber++;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_Download_f
|
||||
|
||||
Request a download from the server
|
||||
===============
|
||||
*/
|
||||
void CL_Download_f (void)
|
||||
{
|
||||
string filename;
|
||||
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
Msg("Usage: download <filename>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
com.sprintf(filename, "%s", Cmd_Argv(1));
|
||||
|
||||
if (com.strstr (filename, ".."))
|
||||
{
|
||||
Msg ("Refusing to download a path with ..\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (FS_LoadFile (filename, NULL))
|
||||
{
|
||||
// it exists, no need to download
|
||||
Msg("File already exists.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
com.strcpy (cls.downloadname, filename);
|
||||
com.strcpy (cls.downloadtempname, filename);
|
||||
|
||||
Msg ("Downloading %s\n", cls.downloadname);
|
||||
|
||||
// download to a temp name, and only rename
|
||||
// to the real name when done, so if interrupted
|
||||
// a runt file wont be left
|
||||
|
||||
|
||||
// download to a temp name, and only rename
|
||||
// to the real name when done, so if interrupted
|
||||
// a runt file wont be left
|
||||
FS_StripExtension (cls.downloadtempname);
|
||||
FS_DefaultExtension(cls.downloadtempname, ".tmp");
|
||||
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, va("download %s", cls.downloadname));
|
||||
cls.downloadnumber++;
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
CL_RegisterSounds
|
||||
======================
|
||||
*/
|
||||
void CL_RegisterSounds (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
S_BeginRegistration();
|
||||
for (i = 1; i < MAX_SOUNDS; i++)
|
||||
{
|
||||
if (!cl.configstrings[CS_SOUNDS+i][0]) break;
|
||||
cl.sound_precache[i] = S_RegisterSound (cl.configstrings[CS_SOUNDS+i]);
|
||||
Sys_SendKeyEvents (); // pump message loop
|
||||
}
|
||||
S_EndRegistration();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ParseDownload
|
||||
|
@ -185,38 +89,39 @@ void CL_ParseDownload( sizebuf_t *msg )
|
|||
// read the data
|
||||
size = MSG_ReadShort( msg );
|
||||
percent = MSG_ReadByte( msg );
|
||||
if (size == -1)
|
||||
|
||||
if( size == -1 )
|
||||
{
|
||||
Msg("Server does not have this file.\n");
|
||||
if (cls.download)
|
||||
Msg( "Server does not have this file.\n" );
|
||||
if( cls.download )
|
||||
{
|
||||
// if here, we tried to resume a file but the server said no
|
||||
FS_Close(cls.download);
|
||||
FS_Close( cls.download );
|
||||
cls.download = NULL;
|
||||
}
|
||||
CL_RequestNextDownload ();
|
||||
CL_RequestNextDownload();
|
||||
return;
|
||||
}
|
||||
|
||||
// open the file if not opened yet
|
||||
if (!cls.download)
|
||||
if( !cls.download )
|
||||
{
|
||||
CL_DownloadFileName(name, sizeof(name), cls.downloadtempname);
|
||||
com.strncpy( name, cls.downloadtempname, MAX_STRING );
|
||||
cls.download = FS_Open ( name, "wb" );
|
||||
|
||||
cls.download = FS_Open (name, "wb");
|
||||
if (!cls.download)
|
||||
if( !cls.download )
|
||||
{
|
||||
msg->readcount += size;
|
||||
Msg ("Failed to open %s\n", cls.downloadtempname);
|
||||
CL_RequestNextDownload ();
|
||||
Msg( "Failed to open %s\n", cls.downloadtempname );
|
||||
CL_RequestNextDownload();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FS_Write (cls.download, msg->data + msg->readcount, size );
|
||||
FS_Write( cls.download, msg->data + msg->readcount, size );
|
||||
msg->readcount += size;
|
||||
|
||||
if (percent != 100)
|
||||
if( percent != 100 )
|
||||
{
|
||||
// request next block
|
||||
cls.downloadpercent = percent;
|
||||
|
@ -227,24 +132,41 @@ void CL_ParseDownload( sizebuf_t *msg )
|
|||
{
|
||||
string oldn, newn;
|
||||
|
||||
FS_Close (cls.download);
|
||||
FS_Close( cls.download );
|
||||
|
||||
// rename the temp file to it's final name
|
||||
CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname);
|
||||
CL_DownloadFileName(newn, sizeof(newn), cls.downloadname);
|
||||
r = rename (oldn, newn);
|
||||
if (r)
|
||||
Msg ("failed to rename.\n");
|
||||
com.strncpy( oldn, cls.downloadtempname, MAX_STRING );
|
||||
com.strncpy( newn, cls.downloadname, MAX_STRING );
|
||||
r = rename( oldn, newn );
|
||||
if( r ) MsgDev( D_ERROR, "failed to rename.\n" );
|
||||
|
||||
cls.download = NULL;
|
||||
cls.downloadpercent = 0;
|
||||
|
||||
// get another file if needed
|
||||
|
||||
CL_RequestNextDownload ();
|
||||
CL_RequestNextDownload();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
CL_RegisterSounds
|
||||
======================
|
||||
*/
|
||||
void CL_RegisterSounds( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
S_BeginRegistration();
|
||||
for( i = 1; i < MAX_SOUNDS; i++ )
|
||||
{
|
||||
if (!cl.configstrings[CS_SOUNDS+i][0]) break;
|
||||
cl.sound_precache[i] = S_RegisterSound (cl.configstrings[CS_SOUNDS+i]);
|
||||
Sys_SendKeyEvents(); // pump message loop
|
||||
}
|
||||
S_EndRegistration();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================================================================
|
||||
|
@ -274,36 +196,25 @@ void CL_ParseServerData( sizebuf_t *msg )
|
|||
i = MSG_ReadLong( msg );
|
||||
cls.serverProtocol = i;
|
||||
|
||||
if( i != PROTOCOL_VERSION ) Host_Error("Server returned version %i, not %i", i, PROTOCOL_VERSION );
|
||||
if( i != PROTOCOL_VERSION )
|
||||
Host_Error("Server use invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION );
|
||||
|
||||
cl.servercount = MSG_ReadLong( msg );
|
||||
|
||||
// parse player entity number
|
||||
cl.playernum = MSG_ReadShort( msg );
|
||||
|
||||
// get the full level name
|
||||
str = MSG_ReadString( msg );
|
||||
|
||||
if( cl.playernum == -1 )
|
||||
{
|
||||
// playing a cinematic or showing a pic, not a level
|
||||
SCR_PlayCinematic( str, 0 );
|
||||
}
|
||||
else
|
||||
// get splash name
|
||||
Cvar_Set( "cl_levelshot_name", va("background/%s.tga", str ));
|
||||
Cvar_SetValue("scr_loading", 0.0f ); // reset progress bar
|
||||
if(!FS_FileExists(va("gfx/%s", Cvar_VariableString("cl_levelshot_name"))))
|
||||
{
|
||||
// get splash name
|
||||
Cvar_Set( "cl_levelshot_name", va("background/%s.tga", str ));
|
||||
Cvar_SetValue("scr_loading", 0.0f ); // reset progress bar
|
||||
if(!FS_FileExists(va("gfx/%s", Cvar_VariableString("cl_levelshot_name"))))
|
||||
{
|
||||
Cvar_Set("cl_levelshot_name", "common/black");
|
||||
cl.make_levelshot = true; // make levelshot
|
||||
}
|
||||
// seperate the printfs so the server message can have a color
|
||||
Msg("\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
|
||||
// need to prep refresh at next oportunity
|
||||
cl.refresh_prepped = false;
|
||||
Cvar_Set("cl_levelshot_name", "common/black");
|
||||
cl.make_levelshot = true; // make levelshot
|
||||
}
|
||||
// seperate the printfs so the server message can have a color
|
||||
Msg("\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n");
|
||||
// need to prep refresh at next oportunity
|
||||
cl.refresh_prepped = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -321,121 +232,13 @@ void CL_ParseBaseline( sizebuf_t *msg )
|
|||
memset( &nullstate, 0, sizeof(nullstate));
|
||||
newnum = MSG_ReadBits( msg, NET_WORD );
|
||||
|
||||
// allocate edicts
|
||||
// increase edicts
|
||||
while( newnum >= prog->num_edicts ) PRVM_ED_Alloc();
|
||||
ent = PRVM_EDICT_NUM( newnum );
|
||||
|
||||
MSG_ReadDeltaEntity( msg, &nullstate, &ent->priv.cl->baseline, newnum );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
CL_LoadClientinfo
|
||||
|
||||
================
|
||||
*/
|
||||
void CL_LoadClientinfo (clientinfo_t *ci, char *s)
|
||||
{
|
||||
int i;
|
||||
char *t;
|
||||
char model_name[MAX_QPATH];
|
||||
char skin_name[MAX_QPATH];
|
||||
char model_filename[MAX_QPATH];
|
||||
char weapon_filename[MAX_QPATH];
|
||||
|
||||
com.strncpy(ci->cinfo, s, sizeof(ci->cinfo));
|
||||
ci->cinfo[sizeof(ci->cinfo)-1] = 0;
|
||||
|
||||
// isolate the player's name
|
||||
com.strncpy(ci->name, s, sizeof(ci->name));
|
||||
ci->name[sizeof(ci->name)-1] = 0;
|
||||
t = com.strstr (s, "\\");
|
||||
if (t)
|
||||
{
|
||||
ci->name[t-s] = 0;
|
||||
s = t+1;
|
||||
}
|
||||
|
||||
if( *s == 0)
|
||||
{
|
||||
com.sprintf (model_filename, "models/players/gordon/player.mdl");
|
||||
com.sprintf (weapon_filename, "models/weapons/w_glock.mdl");
|
||||
ci->model = re->RegisterModel (model_filename);
|
||||
memset(ci->weaponmodel, 0, sizeof(ci->weaponmodel));
|
||||
ci->weaponmodel[0] = re->RegisterModel (weapon_filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
// isolate the model name
|
||||
com.strcpy (model_name, s);
|
||||
t = com.strstr(model_name, "/");
|
||||
if (!t) t = com.strstr(model_name, "\\");
|
||||
if (!t) t = model_name;
|
||||
*t = 0;
|
||||
|
||||
// isolate the skin name
|
||||
com.strcpy (skin_name, s + com.strlen(model_name) + 1);
|
||||
|
||||
// model file
|
||||
com.sprintf (model_filename, "models/players/%s/player.mdl", model_name);
|
||||
ci->model = re->RegisterModel (model_filename);
|
||||
if (!ci->model)
|
||||
{
|
||||
com.strcpy(model_name, "gordon");
|
||||
com.sprintf (model_filename, "models/players/gordon/player.mdl");
|
||||
ci->model = re->RegisterModel (model_filename);
|
||||
}
|
||||
|
||||
// if we don't have the skin and the model wasn't male,
|
||||
// see if the male has it (this is for CTF's skins)
|
||||
if (!ci->skin && com.stricmp(model_name, "male"))
|
||||
{
|
||||
// change model to male
|
||||
com.strcpy(model_name, "male");
|
||||
com.sprintf (model_filename, "models/players/gordon/player.mdl");
|
||||
ci->model = re->RegisterModel (model_filename);
|
||||
}
|
||||
|
||||
// weapon file
|
||||
for (i = 0; i < num_cl_weaponmodels; i++)
|
||||
{
|
||||
com.sprintf (weapon_filename, "models/weapons/%s", cl_weaponmodels[i]);
|
||||
ci->weaponmodel[i] = re->RegisterModel(weapon_filename);
|
||||
if (!cl_vwep->value) break; // only one when vwep is off
|
||||
}
|
||||
}
|
||||
|
||||
// must have loaded all data types to be valud
|
||||
if (!ci->skin || !ci->model || !ci->weaponmodel[0])
|
||||
{
|
||||
ci->skin = NULL;
|
||||
ci->model = NULL;
|
||||
ci->weaponmodel[0] = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ParseClientinfo
|
||||
|
||||
Load the skin, icon, and model for a client
|
||||
================
|
||||
*/
|
||||
void CL_ParseClientinfo (int player)
|
||||
{
|
||||
char *s;
|
||||
clientinfo_t *ci;
|
||||
|
||||
s = cl.configstrings[player+CS_PLAYERSKINS];
|
||||
|
||||
ci = &cl.clientinfo[player];
|
||||
|
||||
CL_LoadClientinfo (ci, s);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
CL_ParseConfigString
|
||||
|
@ -444,46 +247,34 @@ CL_ParseConfigString
|
|||
void CL_ParseConfigString( sizebuf_t *msg )
|
||||
{
|
||||
int i;
|
||||
char *s;
|
||||
string olds;
|
||||
|
||||
i = MSG_ReadShort( msg );
|
||||
if (i < 0 || i >= MAX_CONFIGSTRINGS) Host_Error("configstring > MAX_CONFIGSTRINGS\n");
|
||||
s = MSG_ReadString( msg );
|
||||
|
||||
com.strncpy (olds, cl.configstrings[i], sizeof(olds));
|
||||
olds[sizeof(olds) - 1] = 0;
|
||||
|
||||
com.strcpy (cl.configstrings[i], s);
|
||||
if( i < 0 || i >= MAX_CONFIGSTRINGS )
|
||||
Host_Error("configstring > MAX_CONFIGSTRINGS\n");
|
||||
com.strcpy( cl.configstrings[i], MSG_ReadString( msg ));
|
||||
|
||||
// do something apropriate
|
||||
|
||||
if (i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES)
|
||||
if( i >= CS_MODELS && i < CS_MODELS+MAX_MODELS )
|
||||
{
|
||||
CL_SetLightstyle (i - CS_LIGHTS);
|
||||
}
|
||||
else if (i >= CS_MODELS && i < CS_MODELS+MAX_MODELS)
|
||||
{
|
||||
if(cl.refresh_prepped)
|
||||
if( cl.refresh_prepped )
|
||||
{
|
||||
cl.model_draw[i-CS_MODELS] = re->RegisterModel( cl.configstrings[i] );
|
||||
re->RegisterModel( cl.configstrings[i], i-CS_MODELS );
|
||||
cl.models[i-CS_MODELS] = pe->RegisterModel( cl.configstrings[i] );
|
||||
}
|
||||
}
|
||||
else if (i >= CS_SOUNDS && i < CS_SOUNDS+MAX_MODELS)
|
||||
else if( i >= CS_SOUNDS && i < CS_SOUNDS+MAX_MODELS )
|
||||
{
|
||||
if (cl.refresh_prepped)
|
||||
cl.sound_precache[i-CS_SOUNDS] = S_RegisterSound (cl.configstrings[i]);
|
||||
if( cl.refresh_prepped )
|
||||
cl.sound_precache[i-CS_SOUNDS] = S_RegisterSound( cl.configstrings[i] );
|
||||
}
|
||||
else if (i >= CS_IMAGES && i < CS_IMAGES+MAX_MODELS)
|
||||
else if( i >= CS_CLASSNAMES && i < CS_CLASSNAMES+MAX_CLASSNAMES )
|
||||
{
|
||||
if (cl.refresh_prepped)
|
||||
cl.image_precache[i-CS_IMAGES] = re->RegisterPic (cl.configstrings[i]);
|
||||
// prvm classnames for search by classname on client vm
|
||||
cl.edict_classnames[i-CS_CLASSNAMES] = PRVM_SetEngineString( cl.configstrings[i] );
|
||||
}
|
||||
else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS+MAX_CLIENTS)
|
||||
else if( i >= CS_LIGHTSTYLES && i < CS_LIGHTSTYLES+MAX_LIGHTSTYLES )
|
||||
{
|
||||
if (cl.refresh_prepped && com.strcmp(olds, s))
|
||||
CL_ParseClientinfo (i-CS_PLAYERSKINS);
|
||||
CL_SetLightstyle( i - CS_LIGHTSTYLES );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -537,11 +328,6 @@ void CL_ParseStartSoundPacket( sizebuf_t *msg )
|
|||
S_StartSound( pos, ent, channel, cl.sound_precache[sound_num], volume, attenuation );
|
||||
}
|
||||
|
||||
void SHOWNET( sizebuf_t *msg, char *s )
|
||||
{
|
||||
if (cl_shownet->value >= 2) Msg ("%3i:%s\n", msg->readcount-1, s);
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ParseServerMessage
|
||||
|
@ -552,11 +338,8 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
|||
char *s;
|
||||
int cmd;
|
||||
|
||||
// if recording demos, copy the message out
|
||||
if (cl_shownet->value == 1) Msg ("%i ",msg->cursize);
|
||||
else if (cl_shownet->value >= 2) Msg ("------------------\n");
|
||||
|
||||
cls.multicast = msg; // client progs can recivied messages too
|
||||
// client progs can recivied messages too
|
||||
cls.multicast = msg;
|
||||
|
||||
// parse the message
|
||||
while( 1 )
|
||||
|
@ -595,7 +378,7 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
|||
Cbuf_AddText( s );
|
||||
break;
|
||||
case svc_serverdata:
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
Cbuf_Execute(); // make sure any stuffed commands are done
|
||||
CL_ParseServerData( msg );
|
||||
break;
|
||||
case svc_configstring:
|
||||
|
@ -616,13 +399,13 @@ void CL_ParseServerMessage( sizebuf_t *msg )
|
|||
case svc_frame:
|
||||
CL_ParseFrame( msg );
|
||||
break;
|
||||
case svc_playerinfo:
|
||||
case svc_clientindex:
|
||||
case svc_packetentities:
|
||||
case svc_deltapacketentities:
|
||||
Host_Error("CL_ParseServerMessage: out of place frame data\n");
|
||||
Host_Error( "CL_ParseServerMessage: out of place frame data\n" );
|
||||
break;
|
||||
case svc_bad:
|
||||
Host_Error("CL_ParseServerMessage: svc_bad\n" );
|
||||
Host_Error( "CL_ParseServerMessage: svc_bad\n" );
|
||||
break;
|
||||
default:
|
||||
// parse user messages
|
||||
|
|
|
@ -90,7 +90,7 @@ StudioEvent
|
|||
Event callback for studio models
|
||||
====================
|
||||
*/
|
||||
void CL_StudioEvent ( mstudioevent_t *event, entity_t *ent )
|
||||
void CL_StudioEvent ( mstudioevent_t *event, entity_state_t *ent )
|
||||
{
|
||||
// setup args
|
||||
PRVM_G_FLOAT(OFS_PARM0) = (float)event->event;
|
||||
|
|
|
@ -19,6 +19,7 @@ typedef enum
|
|||
DPVERROR_COLORMASKSOVERLAP,
|
||||
DPVERROR_COLORMASKSEXCEEDBPP,
|
||||
DPVERROR_UNSUPPORTEDBPP,
|
||||
DPVERROR_UNKNOWN
|
||||
} e_dpv_errors;
|
||||
|
||||
typedef enum
|
||||
|
@ -579,6 +580,8 @@ int dpv_video( void *stream, void *imagedata, uint Rmask, uint Gmask, uint Bmask
|
|||
uint framedatasize;
|
||||
char t[4];
|
||||
|
||||
if( !stream ) return DPVERROR_UNKNOWN;
|
||||
|
||||
s->error = DPVERROR_NONE;
|
||||
if( dpv_setpixelformat( s, Rmask, Gmask, Bmask, bpp ))
|
||||
return s->error;
|
||||
|
@ -629,9 +632,7 @@ void CIN_StopCinematic( void )
|
|||
if( cin_state == cin_playback )
|
||||
{
|
||||
cin_state = cin_firstframe;
|
||||
// let game known about movie state
|
||||
cls.state = ca_disconnected;
|
||||
Cbuf_ExecuteText(EXEC_APPEND, "killserver\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -736,8 +737,9 @@ bool CIN_PlayCinematic( const char *filename )
|
|||
frame_num = -1;
|
||||
frame_rate = dpv_getframerate( stream );
|
||||
start_time = cls.realtime;
|
||||
com.strncpy( cls.servername, filename, sizeof(cls.servername));
|
||||
cls.state = ca_cinematic;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -786,14 +788,23 @@ void SCR_StopCinematic( void )
|
|||
|
||||
/*
|
||||
====================
|
||||
SCR_FinishCinematic
|
||||
CL_PlayVideo_f
|
||||
|
||||
Called when either the cinematic completes, or it is aborted
|
||||
movie <moviename>
|
||||
====================
|
||||
*/
|
||||
void SCR_FinishCinematic( void )
|
||||
void CL_PlayVideo_f( void )
|
||||
{
|
||||
// tell the server to advance to the next map / cinematic
|
||||
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_Print( &cls.netchan.message, va("nextserver %i\n", cl.servercount));
|
||||
if( Cmd_Argc() != 2 )
|
||||
{
|
||||
Msg( "movie <moviename>\n" );
|
||||
return;
|
||||
}
|
||||
if( cls.state == ca_active )
|
||||
{
|
||||
// killserver first
|
||||
Cbuf_AddText(va("killserver\n; wait\n; movie %s\n;", Cmd_Argv(1)));
|
||||
return;
|
||||
}
|
||||
SCR_PlayCinematic( Cmd_Argv(1), 0 );
|
||||
}
|
|
@ -22,42 +22,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "common.h"
|
||||
#include "client.h"
|
||||
|
||||
// refdef ents
|
||||
#define MAX_ENTITIES 4096 // FIXME: wrote dynamic allocator
|
||||
|
||||
//=============
|
||||
//
|
||||
// development tools for weapons
|
||||
//
|
||||
model_t *gun_model;
|
||||
|
||||
//=============
|
||||
|
||||
cvar_t *crosshair;
|
||||
cvar_t *cl_testparticles;
|
||||
cvar_t *cl_testentities;
|
||||
cvar_t *cl_testlights;
|
||||
cvar_t *cl_testblend;
|
||||
|
||||
cvar_t *cl_stats;
|
||||
|
||||
int r_numdlights;
|
||||
dlight_t r_dlights[MAX_DLIGHTS];
|
||||
|
||||
int r_numparticles;
|
||||
particle_t r_particles[MAX_PARTICLES];
|
||||
|
||||
lightstyle_t r_lightstyles[MAX_LIGHTSTYLES];
|
||||
|
||||
char cl_weaponmodels[MAX_CLIENTWEAPONMODELS][MAX_QPATH];
|
||||
int num_cl_weaponmodels;
|
||||
|
||||
int entitycmpfnc( const entity_t *a, const entity_t *b )
|
||||
{
|
||||
// all other models are sorted by model then skin
|
||||
return ((int)a->model - (int)b->model);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
V_ClearScene
|
||||
|
@ -65,11 +34,9 @@ V_ClearScene
|
|||
Specifies the model that will be used as the world
|
||||
====================
|
||||
*/
|
||||
void V_ClearScene (void)
|
||||
void V_ClearScene( void )
|
||||
{
|
||||
r_numdlights = 0;
|
||||
cls.ref_numents = 0;
|
||||
r_numparticles = 0;
|
||||
re->ClearScene( &cl.refdef );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -88,109 +55,6 @@ void V_CalcRect( void )
|
|||
scr_vrect.y = scr_vrect.x = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
V_AddEntity
|
||||
|
||||
=====================
|
||||
*/
|
||||
void V_AddEntity (entity_t *ent)
|
||||
{
|
||||
if( cls.ref_numents >= host.max_edicts )
|
||||
return;
|
||||
cls.ref_entities[cls.ref_numents++] = *ent;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
V_AddParticle
|
||||
|
||||
=====================
|
||||
*/
|
||||
void V_AddParticle (vec3_t org, int color, float alpha)
|
||||
{
|
||||
particle_t *p;
|
||||
|
||||
if (r_numparticles >= MAX_PARTICLES)
|
||||
return;
|
||||
p = &r_particles[r_numparticles++];
|
||||
VectorCopy (org, p->origin);
|
||||
p->color = color;
|
||||
p->alpha = alpha;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
V_AddLight
|
||||
|
||||
=====================
|
||||
*/
|
||||
void V_AddLight (vec3_t org, float intensity, float r, float g, float b)
|
||||
{
|
||||
dlight_t *dl;
|
||||
|
||||
if (r_numdlights >= MAX_DLIGHTS)
|
||||
return;
|
||||
dl = &r_dlights[r_numdlights++];
|
||||
VectorCopy (org, dl->origin);
|
||||
dl->intensity = intensity;
|
||||
dl->color[0] = r;
|
||||
dl->color[1] = g;
|
||||
dl->color[2] = b;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
V_AddLightStyle
|
||||
|
||||
=====================
|
||||
*/
|
||||
void V_AddLightStyle( int style, float r, float g, float b )
|
||||
{
|
||||
lightstyle_t *ls;
|
||||
|
||||
if (style < 0 || style > MAX_LIGHTSTYLES)
|
||||
Host_Error("V_AddLightStyle: invalid light style %i\n", style);
|
||||
ls = &r_lightstyles[style];
|
||||
|
||||
ls->white = r+g+b;
|
||||
ls->rgb[0] = r;
|
||||
ls->rgb[1] = g;
|
||||
ls->rgb[2] = b;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
V_TestParticles
|
||||
|
||||
If cl_testparticles is set, create 4096 particles in the view
|
||||
================
|
||||
*/
|
||||
void V_TestParticles (void)
|
||||
{
|
||||
particle_t *p;
|
||||
int i, j;
|
||||
float d, r, u;
|
||||
|
||||
r_numparticles = MAX_PARTICLES;
|
||||
for (i=0 ; i<r_numparticles ; i++)
|
||||
{
|
||||
d = i*0.25;
|
||||
r = 4*((i&7)-3.5);
|
||||
u = 4*(((i>>3)&7)-3.5);
|
||||
p = &r_particles[i];
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
p->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*d +
|
||||
cl.v_right[j]*r + cl.v_up[j]*u;
|
||||
|
||||
p->color = 8;
|
||||
p->alpha = cl_testparticles->value;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
V_TestEntities
|
||||
|
@ -198,25 +62,27 @@ V_TestEntities
|
|||
If cl_testentities is set, create 32 player models
|
||||
================
|
||||
*/
|
||||
void V_TestEntities (void)
|
||||
void V_TestEntities( void )
|
||||
{
|
||||
int i, j;
|
||||
float f, r;
|
||||
entity_t *ent;
|
||||
entity_state_t ent;
|
||||
|
||||
cls.ref_numents = 32;
|
||||
memset( cls.ref_entities, 0, sizeof(entity_t));
|
||||
memset( &ent, 0, sizeof(entity_state_t));
|
||||
cl.refdef.num_entities = 0;
|
||||
|
||||
for( i = 0; i < cls.ref_numents; i++ )
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
ent = &cls.ref_entities[i];
|
||||
|
||||
r = 64 * ((i%4) - 1.5 );
|
||||
f = 64 * (i/4) + 128;
|
||||
|
||||
for( j = 0; j < 3; j++ )
|
||||
ent->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f + cl.v_right[j] * r;
|
||||
ent->model = cl.baseclientinfo.model;
|
||||
ent.origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j] * f + cl.v_right[j] * r;
|
||||
|
||||
ent.model.controller[0] = ent.model.controller[1] = 90.0f;
|
||||
ent.model.controller[2] = ent.model.controller[3] = 180.0f;
|
||||
ent.model.index = cl.frame.ps.model.index;
|
||||
re->AddRefEntity( &cl.refdef, &ent, NULL, 1.0f );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,29 +93,28 @@ V_TestLights
|
|||
If cl_testlights is set, create 32 lights models
|
||||
================
|
||||
*/
|
||||
void V_TestLights (void)
|
||||
void V_TestLights( void )
|
||||
{
|
||||
int i, j;
|
||||
int i, j;
|
||||
float f, r;
|
||||
dlight_t *dl;
|
||||
cdlight_t dl;
|
||||
|
||||
r_numdlights = 32;
|
||||
memset (r_dlights, 0, sizeof(r_dlights));
|
||||
cl.refdef.num_dlights = 0;
|
||||
memset( &dl, 0, sizeof(cdlight_t));
|
||||
|
||||
for (i=0 ; i<r_numdlights ; i++)
|
||||
for( i = 0; i < 32; i++ )
|
||||
{
|
||||
dl = &r_dlights[i];
|
||||
|
||||
r = 64 * ( (i%4) - 1.5 );
|
||||
f = 64 * (i/4) + 128;
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
dl->origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j]*f +
|
||||
cl.v_right[j]*r;
|
||||
dl->color[0] = ((i%6)+1) & 1;
|
||||
dl->color[1] = (((i%6)+1) & 2)>>1;
|
||||
dl->color[2] = (((i%6)+1) & 4)>>2;
|
||||
dl->intensity = 200;
|
||||
for( j = 0; j < 3; j++ )
|
||||
dl.origin[j] = cl.refdef.vieworg[j] + cl.v_forward[j] * f + cl.v_right[j] * r;
|
||||
|
||||
dl.color[0] = ((i%6)+1) & 1;
|
||||
dl.color[1] = (((i%6)+1) & 2)>>1;
|
||||
dl.color[2] = (((i%6)+1) & 4)>>2;
|
||||
dl.radius = 200;
|
||||
re->AddDynLight( &cl.refdef, dl.origin, dl.color, dl.radius );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -268,13 +133,12 @@ void CL_PrepRefresh( void )
|
|||
string name;
|
||||
float rotate;
|
||||
vec3_t axis;
|
||||
int i;
|
||||
int mdlcount = 0, imgcount = 0, cl_count = 0;
|
||||
int i, mdlcount = 0;
|
||||
|
||||
if (!cl.configstrings[CS_MODELS+1][0])
|
||||
return; // no map loaded
|
||||
|
||||
Msg("CL_PrepRefresh: %s\n", cl.configstrings[CS_NAME] );
|
||||
Msg( "CL_PrepRefresh: %s\n", cl.configstrings[CS_NAME] );
|
||||
|
||||
// let the render dll load the map
|
||||
FS_FileBase( cl.configstrings[CS_MODELS+1], mapname );
|
||||
|
@ -282,68 +146,46 @@ void CL_PrepRefresh( void )
|
|||
re->BeginRegistration( mapname ); // load map
|
||||
SCR_UpdateScreen();
|
||||
|
||||
num_cl_weaponmodels = 1;
|
||||
com.strcpy(cl_weaponmodels[0], "v_glock.mdl");
|
||||
|
||||
for( i = 1; i < MAX_MODELS; i++ )
|
||||
{
|
||||
if(!cl.configstrings[CS_MODELS+i][0])
|
||||
break;
|
||||
mdlcount++; // total num models
|
||||
}
|
||||
for( i = 1; i < MAX_IMAGES; i++ )
|
||||
{
|
||||
if(!cl.configstrings[CS_IMAGES+i][0])
|
||||
break;
|
||||
imgcount++; // total num models
|
||||
}
|
||||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(!cl.configstrings[CS_PLAYERSKINS+i][0])
|
||||
continue;
|
||||
cl_count++;
|
||||
}
|
||||
|
||||
|
||||
// create thread here ?
|
||||
for (i = 1; i < MAX_MODELS && cl.configstrings[CS_MODELS+i][0]; i++)
|
||||
for( i = 0; i < pe->NumTextures(); i++ )
|
||||
{
|
||||
if(!re->RegisterImage( cl.configstrings[CS_MODELS+1], i ))
|
||||
{
|
||||
Cvar_SetValue( "scr_loading", scr_loading->value + 70.0f );
|
||||
break; // hey, textures already loaded!
|
||||
}
|
||||
SCR_UpdateScreen();
|
||||
Sys_SendKeyEvents(); // pump message loop
|
||||
|
||||
Cvar_SetValue("scr_loading", scr_loading->value + 70.0f / pe->NumTextures());
|
||||
}
|
||||
|
||||
// create thread here ?
|
||||
for( i = 1; i < MAX_MODELS && cl.configstrings[CS_MODELS+i][0]; i++ )
|
||||
{
|
||||
com.strncpy( name, cl.configstrings[CS_MODELS+i], MAX_STRING );
|
||||
SCR_UpdateScreen();
|
||||
Sys_SendKeyEvents(); // pump message loop
|
||||
|
||||
cl.model_draw[i] = re->RegisterModel( name );
|
||||
re->RegisterModel( name, i );
|
||||
cl.models[i] = pe->RegisterModel( name );
|
||||
Cvar_SetValue("scr_loading", scr_loading->value + 50.0f/mdlcount );
|
||||
SCR_UpdateScreen();
|
||||
Cvar_SetValue("scr_loading", scr_loading->value + 30.0f/mdlcount );
|
||||
}
|
||||
|
||||
// create thread here ?
|
||||
SCR_UpdateScreen();
|
||||
for (i = 1; i < MAX_IMAGES && cl.configstrings[CS_IMAGES+i][0]; i++)
|
||||
{
|
||||
cl.image_precache[i] = re->RegisterPic (cl.configstrings[CS_IMAGES+i]);
|
||||
Sys_SendKeyEvents (); // pump message loop
|
||||
Cvar_SetValue("scr_loading", scr_loading->value + 3.0f/imgcount );
|
||||
SCR_UpdateScreen();
|
||||
}
|
||||
|
||||
// create thread here ?
|
||||
for (i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(!cl.configstrings[CS_PLAYERSKINS+i][0]) continue;
|
||||
Cvar_SetValue("scr_loading", scr_loading->value + 2.0f/cl_count );
|
||||
SCR_UpdateScreen ();
|
||||
Sys_SendKeyEvents(); // pump message loop
|
||||
CL_ParseClientinfo(i);
|
||||
}
|
||||
|
||||
CL_LoadClientinfo (&cl.baseclientinfo, "unnamed\\male/grunt");
|
||||
for( i = 1; i < MAX_CLASSNAMES && cl.configstrings[CS_CLASSNAMES+i][0]; i++ )
|
||||
cl.edict_classnames[i] = PRVM_SetEngineString( cl.configstrings[CS_CLASSNAMES+i]);
|
||||
|
||||
// set sky textures and speed
|
||||
SCR_UpdateScreen();
|
||||
rotate = com.atof(cl.configstrings[CS_SKYROTATE]);
|
||||
com.atov( axis, cl.configstrings[CS_SKYAXIS], 3 );
|
||||
re->SetSky( cl.configstrings[CS_SKY], rotate, axis);
|
||||
rotate = com.atof(cl.configstrings[CS_SKYSPEED]);
|
||||
com.atov( axis, cl.configstrings[CS_SKYANGLES], 3 );
|
||||
re->SetSky( cl.configstrings[CS_SKYNAME], rotate, axis );
|
||||
Cvar_SetValue("scr_loading", 100.0f ); // all done
|
||||
|
||||
re->EndRegistration (); // the render can now free unneeded stuff
|
||||
|
@ -362,6 +204,10 @@ float V_CalcFov( float fov_x, float width, float height )
|
|||
{
|
||||
float fov_y, x, rad = 360.0f * M_PI;
|
||||
|
||||
// check to avoid division by zero
|
||||
if( fov_x == 0 ) Host_Error( "V_CalcFov: null fov!\n" );
|
||||
|
||||
// make sure that fov in-range
|
||||
fov_x = bound( 1, fov_x, 179 );
|
||||
x = width / tan( fov_x / rad );
|
||||
fov_y = atan2( height, x );
|
||||
|
@ -388,8 +234,7 @@ void V_RenderView( void )
|
|||
if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) )
|
||||
{
|
||||
cl.force_refdef = false;
|
||||
|
||||
V_ClearScene ();
|
||||
V_ClearScene();
|
||||
|
||||
// build a refresh entity list and calc cl.sim*
|
||||
// this also calls CL_CalcViewValues which loads
|
||||
|
@ -397,18 +242,14 @@ void V_RenderView( void )
|
|||
CL_VM_Begin();
|
||||
CL_AddEntities ();
|
||||
|
||||
if (cl_testparticles->value)
|
||||
V_TestParticles ();
|
||||
if (cl_testentities->value)
|
||||
V_TestEntities ();
|
||||
if (cl_testlights->value)
|
||||
V_TestLights ();
|
||||
if (cl_testblend->value)
|
||||
if( cl_testentities->value ) V_TestEntities();
|
||||
if( cl_testlights->value ) V_TestLights();
|
||||
if( cl_testblend->value)
|
||||
{
|
||||
cl.refdef.blend[0] = 1;
|
||||
cl.refdef.blend[1] = 0.5;
|
||||
cl.refdef.blend[2] = 0.25;
|
||||
cl.refdef.blend[3] = 0.5;
|
||||
cl.refdef.blend[3] = 0.8;
|
||||
}
|
||||
|
||||
// never let it sit exactly on a node line, because a water plane can
|
||||
|
@ -418,41 +259,14 @@ void V_RenderView( void )
|
|||
cl.refdef.vieworg[1] += 1.0 / 32;
|
||||
cl.refdef.vieworg[2] += 1.0 / 32;
|
||||
|
||||
cl.refdef.x = scr_vrect.x;
|
||||
cl.refdef.y = scr_vrect.y;
|
||||
cl.refdef.width = scr_vrect.width;
|
||||
cl.refdef.height = scr_vrect.height;
|
||||
cl.refdef.fov_y = V_CalcFov (cl.refdef.fov_x, cl.refdef.width, cl.refdef.height);
|
||||
cl.refdef.time = cls.realtime * 0.001f; // render use realtime now
|
||||
|
||||
cl.refdef.areabits = cl.frame.areabits;
|
||||
|
||||
if( !cl_add_entities->value )
|
||||
cls.ref_numents = 0;
|
||||
if (!cl_add_particles->value)
|
||||
r_numparticles = 0;
|
||||
if (!cl_add_lights->value)
|
||||
r_numdlights = 0;
|
||||
if (!cl_add_blend->value)
|
||||
{
|
||||
VectorClear (cl.refdef.blend);
|
||||
}
|
||||
|
||||
cl.refdef.num_entities = cls.ref_numents;
|
||||
cl.refdef.entities = cls.ref_entities;
|
||||
cl.refdef.num_particles = r_numparticles;
|
||||
cl.refdef.particles = r_particles;
|
||||
cl.refdef.num_dlights = r_numdlights;
|
||||
cl.refdef.dlights = r_dlights;
|
||||
cl.refdef.lightstyles = r_lightstyles;
|
||||
|
||||
cl.refdef.rdflags = cl.frame.ps.effects;
|
||||
|
||||
// sort entities for better cache locality
|
||||
qsort( cl.refdef.entities, cl.refdef.num_entities, sizeof( cl.refdef.entities[0] ), (int(*)(const void *, const void *))entitycmpfnc );
|
||||
Mem_Copy( &cl.refdef.rect, &scr_vrect, sizeof(vrect_t));
|
||||
|
||||
cl.refdef.areabits = cl.frame.areabits;
|
||||
cl.refdef.rdflags = cl.frame.ps.renderfx;
|
||||
cl.refdef.fov_y = V_CalcFov( cl.refdef.fov_x, cl.refdef.rect.width, cl.refdef.rect.height );
|
||||
cl.refdef.time = cls.realtime * 0.001f; // render use realtime now
|
||||
}
|
||||
re->RenderFrame (&cl.refdef);
|
||||
if( cl_stats->value ) Msg("ent:%i lt:%i part:%i\n", cls.ref_numents, r_numdlights, r_numparticles );
|
||||
re->RenderFrame( &cl.refdef );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -464,11 +278,9 @@ V_PreRender
|
|||
bool V_PreRender( void )
|
||||
{
|
||||
// too early
|
||||
if(!re) return false;
|
||||
if( !re ) return false;
|
||||
|
||||
re->BeginFrame();
|
||||
|
||||
// clear screen
|
||||
SCR_FillRect( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, g_color_table[0] );
|
||||
|
||||
return true;
|
||||
|
@ -508,12 +320,9 @@ void V_Init (void)
|
|||
|
||||
crosshair = Cvar_Get ("crosshair", "0", CVAR_ARCHIVE, "crosshair style" );
|
||||
cl_testblend = Cvar_Get ("cl_testblend", "0", 0, "test blending" );
|
||||
cl_testparticles = Cvar_Get ("cl_testparticles", "0", 0, "test particle engine" );
|
||||
cl_testentities = Cvar_Get ("cl_testentities", "0", 0, "test client entities" );
|
||||
cl_testlights = Cvar_Get ("cl_testlights", "0", 0, "test dynamic lights" );
|
||||
cl_stats = Cvar_Get ("cl_stats", "0", 0, "enable client stats" );
|
||||
cls.mempool = Mem_AllocPool( "Client Static" );
|
||||
cls.ref_entities = Mem_Alloc( cls.mempool, sizeof(entity_t) * host.max_edicts );
|
||||
}
|
||||
|
||||
void V_Shutdown( void )
|
||||
|
|
|
@ -53,20 +53,6 @@ typedef struct field_s
|
|||
int maxchars; // menu stuff
|
||||
} field_t;
|
||||
|
||||
#define MAX_CLIENTWEAPONMODELS 20 // PGM -- upped from 16 to fit the chainfist vwep
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[MAX_QPATH];
|
||||
char cinfo[MAX_QPATH];
|
||||
image_t *skin;
|
||||
model_t *model;
|
||||
model_t *weaponmodel[MAX_CLIENTWEAPONMODELS];
|
||||
} clientinfo_t;
|
||||
|
||||
extern char cl_weaponmodels[MAX_CLIENTWEAPONMODELS][MAX_QPATH];
|
||||
extern int num_cl_weaponmodels;
|
||||
|
||||
#define CMD_BACKUP 64 // allow a lot of command backups for very fast systems
|
||||
#define CMD_MASK (CMD_BACKUP - 1)
|
||||
|
||||
|
@ -139,15 +125,11 @@ typedef struct
|
|||
//
|
||||
// locally derived information from server state
|
||||
//
|
||||
model_t *model_draw[MAX_MODELS];
|
||||
cmodel_t *models[MAX_MODELS];
|
||||
cmodel_t *worldmodel;
|
||||
|
||||
string_t edict_classnames[MAX_CLASSNAMES];
|
||||
sound_t sound_precache[MAX_SOUNDS];
|
||||
image_t *image_precache[MAX_IMAGES];
|
||||
|
||||
clientinfo_t clientinfo[MAX_CLIENTS];
|
||||
clientinfo_t baseclientinfo;
|
||||
} client_t;
|
||||
|
||||
extern client_t cl;
|
||||
|
@ -219,12 +201,9 @@ typedef struct
|
|||
keydest_t key_dest;
|
||||
byte *mempool;
|
||||
|
||||
int ref_numents;
|
||||
entity_t *ref_entities;
|
||||
|
||||
int framecount;
|
||||
dword realtime; // always increasing, no clamping, etc
|
||||
float frametime; // seconds since last frame
|
||||
float frametime; // seconds since last frame
|
||||
|
||||
// connection information
|
||||
string servername; // name of server from original connect
|
||||
|
@ -243,11 +222,11 @@ typedef struct
|
|||
dltype_t downloadtype;
|
||||
int downloadpercent;
|
||||
|
||||
// demo recording info must be here, so it isn't cleared on level change
|
||||
// demo recording info must be here, so it isn't clearing on level change
|
||||
bool demorecording;
|
||||
bool demoplayback;
|
||||
bool demowaiting; // don't record until a non-delta message is received
|
||||
string demoname; // for demo looping
|
||||
bool demowaiting; // don't record until a non-delta message is received
|
||||
string demoname; // for demo looping
|
||||
|
||||
file_t *demofile;
|
||||
serverinfo_t serverlist[MAX_SERVERS]; // servers to join
|
||||
|
@ -282,13 +261,6 @@ SCREEN CONSTS
|
|||
#define GIANTCHAR_WIDTH 32
|
||||
#define GIANTCHAR_HEIGHT 48
|
||||
|
||||
typedef struct vrect_s
|
||||
{
|
||||
int x, y;
|
||||
int width;
|
||||
int height;
|
||||
} vrect_t;
|
||||
|
||||
extern vrect_t scr_vrect; // position of render window
|
||||
|
||||
// console color typeing
|
||||
|
@ -352,10 +324,13 @@ extern cvar_t *scr_showpause;
|
|||
|
||||
typedef struct
|
||||
{
|
||||
int key; // so entities can reuse same entry
|
||||
vec3_t color;
|
||||
// these values shared with dlight_t so don't move them
|
||||
vec3_t origin;
|
||||
vec3_t color;
|
||||
float radius;
|
||||
|
||||
// cdlight_t private starts here
|
||||
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
|
||||
|
@ -371,9 +346,7 @@ extern entity_state_t cl_parse_entities[MAX_PARSE_ENTITIES];
|
|||
|
||||
//=============================================================================
|
||||
|
||||
bool CL_CheckOrDownloadFile (char *filename);
|
||||
|
||||
void CL_AddNetgraph (void);
|
||||
bool CL_CheckOrDownloadFile( const char *filename );
|
||||
|
||||
void CL_TeleporterParticles (entity_state_t *ent);
|
||||
void CL_ParticleEffect (vec3_t org, vec3_t dir, int color, int count);
|
||||
|
@ -387,8 +360,6 @@ void CL_ParticleEffect3 (vec3_t org, vec3_t dir, int color, int count);
|
|||
|
||||
// ========
|
||||
// PGM
|
||||
#define MAX_PARTICLES 32768
|
||||
|
||||
typedef struct cparticle_s
|
||||
{
|
||||
struct cparticle_s *next;
|
||||
|
@ -547,10 +518,7 @@ _inline edict_t *CLVM_EDICT_NUM( int entnum )
|
|||
// cl_parse.c
|
||||
//
|
||||
void CL_ParseServerMessage( sizebuf_t *msg );
|
||||
void CL_LoadClientinfo (clientinfo_t *ci, char *s);
|
||||
void SHOWNET( sizebuf_t *msg, char *s );
|
||||
void CL_ParseClientinfo( int player );
|
||||
void CL_Download_f (void);
|
||||
void CL_Download_f( void );
|
||||
|
||||
//
|
||||
// cl_scrn.c
|
||||
|
@ -584,10 +552,6 @@ void V_PostRender( void );
|
|||
void V_RenderView( void );
|
||||
void V_RenderLogo( void );
|
||||
void V_RenderSplash( void );
|
||||
void V_AddEntity (entity_t *ent);
|
||||
void V_AddParticle (vec3_t org, int color, float alpha);
|
||||
void V_AddLight (vec3_t org, float intensity, float r, float g, float b);
|
||||
void V_AddLightStyle (int style, float r, float g, float b);
|
||||
float V_CalcFov( float fov_x, float width, float height );
|
||||
|
||||
//
|
||||
|
@ -609,7 +573,7 @@ void CL_AddLoopingSounds( void );
|
|||
cdlight_t *CL_AllocDlight (int key);
|
||||
void CL_AddParticles (void);
|
||||
void CL_ClearEffects( void );
|
||||
void CL_StudioEvent( mstudioevent_t *event, entity_t *ent );
|
||||
void CL_StudioEvent( mstudioevent_t *event, entity_state_t *ent );
|
||||
|
||||
//
|
||||
// cl_pred.c
|
||||
|
@ -687,6 +651,6 @@ void SCR_RunCinematic( void );
|
|||
void SCR_StopCinematic( void );
|
||||
void SCR_ResetCinematic( void );
|
||||
int SCR_GetCinematicState( void );
|
||||
void SCR_FinishCinematic( void );
|
||||
void CL_PlayVideo_f( void );
|
||||
|
||||
#endif//CLIENT_H
|
|
@ -1291,10 +1291,11 @@ void VM_drawmodel( void )
|
|||
{
|
||||
float *size, *pos, *origin, *angles;
|
||||
const char *modname;
|
||||
refdef_t refdef;
|
||||
vrect_t rect;
|
||||
static refdef_t refdef;
|
||||
int sequence;
|
||||
entity_state_t ent;
|
||||
static float frame;
|
||||
entity_t entity;
|
||||
|
||||
if(!VM_ValidateArgs( "drawmodel", 4 ))
|
||||
return;
|
||||
|
@ -1307,41 +1308,32 @@ void VM_drawmodel( void )
|
|||
sequence = (int)PRVM_G_FLOAT(OFS_PARM5);
|
||||
|
||||
VM_ValidateString(PRVM_G_STRING(OFS_PARM2));
|
||||
memset( &entity, 0, sizeof( entity ));
|
||||
memset( &refdef, 0, sizeof( refdef ) );
|
||||
memset( &ent, 0, sizeof( ent ));
|
||||
|
||||
SCR_AdjustSize( &pos[0], &pos[1], &size[0], &size[1] );
|
||||
|
||||
refdef.x = pos[0];
|
||||
refdef.y = pos[1];
|
||||
refdef.width = size[0];
|
||||
refdef.height = size[1];
|
||||
rect.x = pos[0]; rect.y = pos[1]; rect.width = size[0]; rect.height = size[1];
|
||||
Mem_Copy( &refdef.rect, &rect, sizeof(vrect_t));
|
||||
|
||||
refdef.fov_x = 50;
|
||||
refdef.fov_y = V_CalcFov( refdef.fov_x, refdef.width, refdef.height );
|
||||
refdef.fov_y = V_CalcFov( refdef.fov_x, refdef.rect.width, refdef.rect.height );
|
||||
refdef.time = cls.realtime * 0.001f;
|
||||
|
||||
entity.model = re->RegisterModel( (char *)modname );
|
||||
entity.flags = RF_FULLBRIGHT;
|
||||
VectorCopy( origin, entity.origin );
|
||||
VectorCopy( entity.origin, entity.oldorigin );
|
||||
VectorCopy( angles, entity.angles );
|
||||
entity.frame = frame += 0.7f;//FXIME
|
||||
entity.sequence = sequence;
|
||||
entity.prev.frame = 0;
|
||||
entity.backlerp = 0.0;
|
||||
entity.controller[0] = 90.0;
|
||||
entity.controller[1] = 90.0;
|
||||
entity.controller[2] = 180.0;
|
||||
entity.controller[3] = 180.0;
|
||||
|
||||
refdef.areabits = 0;
|
||||
refdef.num_entities = 1;
|
||||
refdef.entities = &entity;
|
||||
refdef.lightstyles = 0;
|
||||
refdef.rdflags = RDF_NOWORLDMODEL;
|
||||
|
||||
re->ClearScene( &refdef );
|
||||
re->RegisterModel( modname, MAX_MODELS - 1 );
|
||||
ent.renderfx = RF_FULLBRIGHT;
|
||||
ent.model.sequence = sequence;
|
||||
ent.model.index = MAX_MODELS - 1;
|
||||
VectorCopy( origin, ent.origin );
|
||||
VectorCopy( origin, ent.old_origin );
|
||||
VectorCopy( angles, ent.angles );
|
||||
ent.model.controller[0] = ent.model.controller[1] = 90.0;
|
||||
ent.model.controller[2] = ent.model.controller[3] = 180.0;
|
||||
|
||||
ent.model.frame = frame += 0.7f;//FXIME
|
||||
|
||||
re->AddRefEntity( &refdef, &ent, NULL, 1.0f );
|
||||
re->RenderFrame( &refdef );
|
||||
re->EndFrame();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
static net_field_t ent_fields[] =
|
||||
{
|
||||
{ ES_FIELD(ed_type), NET_BYTE, true },
|
||||
{ ES_FIELD(classname), NET_WORD, true },
|
||||
{ ES_FIELD(soundindex), NET_WORD, false }, // 512 sounds ( OpenAL software limit is 255 )
|
||||
{ ES_FIELD(origin[0]), NET_FLOAT, false },
|
||||
{ ES_FIELD(origin[1]), NET_FLOAT, false },
|
||||
|
@ -98,16 +99,12 @@ static net_field_t ent_fields[] =
|
|||
{ ES_FIELD(maxspeed), NET_WORD, false }, // send flags (third 4 bytes )
|
||||
{ ES_FIELD(fov), NET_FLOAT, false }, // client horizontal field of view
|
||||
{ ES_FIELD(health), NET_FLOAT, false }, // client health
|
||||
{ ES_FIELD(vmodel.index), NET_WORD, false }, // 4096 models
|
||||
{ ES_FIELD(vmodel.colormap), NET_LONG, false }, // 4096 models
|
||||
{ ES_FIELD(vmodel.sequence), NET_WORD, false }, // 1024 sequences
|
||||
{ ES_FIELD(vmodel.frame), NET_FLOAT, false }, // interpolate value
|
||||
{ ES_FIELD(vmodel.body), NET_BYTE, false }, // 255 bodies
|
||||
{ ES_FIELD(vmodel.skin), NET_BYTE, false }, // 255 skins
|
||||
{ ES_FIELD(pmodel.index), NET_WORD, false }, // 4096 models
|
||||
{ ES_FIELD(pmodel.colormap), NET_LONG, false }, // 4096 models
|
||||
{ ES_FIELD(pmodel.sequence), NET_WORD, false }, // 1024 sequences
|
||||
{ ES_FIELD(vmodel.frame), NET_FLOAT, false }, // interpolate value
|
||||
{ ES_FIELD(pmodel.frame), NET_FLOAT, false }, // interpolate value
|
||||
{ ES_FIELD(pmodel.body), NET_BYTE, false }, // 255 bodies
|
||||
{ ES_FIELD(pmodel.skin), NET_BYTE, false }, // 255 skins
|
||||
{ NULL }, // terminator
|
||||
};
|
||||
|
||||
|
@ -670,62 +667,21 @@ player state communication
|
|||
|
||||
============================================================================
|
||||
*/
|
||||
/*
|
||||
=============
|
||||
MSG_WriteDeltaPlayerstate
|
||||
|
||||
=============
|
||||
*/
|
||||
void MSG_WriteDeltaPlayerstate( entity_state_t *from, entity_state_t *to, sizebuf_t *msg )
|
||||
{
|
||||
entity_state_t dummy;
|
||||
entity_state_t *ops, *ps = to;
|
||||
net_field_t *field, *field2;
|
||||
int *fromF, *toF;
|
||||
int i, j, k;
|
||||
uint flags = 0;
|
||||
|
||||
if( !from )
|
||||
{
|
||||
memset (&dummy, 0, sizeof(dummy));
|
||||
ops = &dummy;
|
||||
}
|
||||
else ops = from;
|
||||
from = to;
|
||||
|
||||
MSG_WriteByte( msg, svc_playerinfo );
|
||||
|
||||
for( i = j = 0, field = field2 = ent_fields; field->name; i++, j++, field++ )
|
||||
{
|
||||
fromF = (int *)((byte *)ops + field->offset );
|
||||
toF = (int *)((byte *)ps + field->offset );
|
||||
if(*fromF != *toF || field->force) flags |= 1<<j;
|
||||
if( j > 31 || !ent_fields[i+1].name) // dump packet
|
||||
{
|
||||
MSG_WriteLong( msg, flags ); // send flags who indicates changes
|
||||
for( k = 0; field2->name; k++, field2++ )
|
||||
{
|
||||
if( k > 31 ) break; // return to main cycle
|
||||
toF = (int *)((byte *)ps + field2->offset );
|
||||
if( flags & 1<<k ) MSG_WriteBits( msg, *toF, field2->bits );
|
||||
}
|
||||
j = flags = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
MSG_ReadDeltaPlayerstate
|
||||
MSG_ParseDeltaPlayer
|
||||
===================
|
||||
*/
|
||||
void MSG_ReadDeltaPlayerstate( sizebuf_t *msg, entity_state_t *from, entity_state_t *to )
|
||||
entity_state_t MSG_ParseDeltaPlayer( entity_state_t *from, entity_state_t *to )
|
||||
{
|
||||
net_field_t *field;
|
||||
int *fromF, *toF;
|
||||
entity_state_t dummy;
|
||||
uint i, flags;
|
||||
int *fromF, *toF, *outF;
|
||||
entity_state_t dummy, result, *out;
|
||||
uint i;
|
||||
|
||||
// alloc space to copy state
|
||||
memset( &result, 0, sizeof( result ));
|
||||
out = &result;
|
||||
|
||||
// clear to old value before delta parsing
|
||||
if( !from )
|
||||
|
@ -733,16 +689,15 @@ void MSG_ReadDeltaPlayerstate( sizebuf_t *msg, entity_state_t *from, entity_stat
|
|||
from = &dummy;
|
||||
memset( &dummy, 0, sizeof( dummy ));
|
||||
}
|
||||
*to = *from;
|
||||
*out = *from;
|
||||
|
||||
for( i = 0, field = ent_fields; field->name; i++, field++ )
|
||||
{
|
||||
// get flags of next packet if LONG out of range
|
||||
if((i & 31) == 0) flags = MSG_ReadLong( msg );
|
||||
fromF = (int *)((byte *)from + field->offset );
|
||||
toF = (int *)((byte *)to + field->offset );
|
||||
|
||||
if(flags & (1<<i)) *toF = MSG_ReadBits( msg, field->bits );
|
||||
else *toF = *fromF; // no change
|
||||
outF = (int *)((byte *)out + field->offset );
|
||||
if( *fromF != *toF ) *outF = *toF;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -57,7 +57,7 @@ enum svc_ops_e
|
|||
svc_configstring, // [short] [string]
|
||||
svc_spawnbaseline, // valid only at spawn
|
||||
svc_download, // [short] size [size bytes]
|
||||
svc_playerinfo, // variable
|
||||
svc_clientindex, // [byte] edictnumber
|
||||
svc_packetentities, // [...]
|
||||
svc_deltapacketentities, // [...]
|
||||
svc_frame, // server frame
|
||||
|
@ -111,14 +111,7 @@ static const net_desc_t NWDesc[] =
|
|||
*/
|
||||
|
||||
// per-level limits
|
||||
#define MAX_DLIGHTS 128 // dynamic lights
|
||||
#define MAX_CLIENTS 256 // absolute limit
|
||||
#define MAX_LIGHTSTYLES 256 // compiler limit
|
||||
#define MAX_SOUNDS 512 // so they cannot be blindly increased
|
||||
#define MAX_IMAGES 256 // hud graphics
|
||||
#define MAX_DECALS 256 // various decals
|
||||
#define MAX_ITEMS 128 // player items
|
||||
#define MAX_GENERAL (MAX_CLIENTS * 2) // general config strings
|
||||
|
||||
|
||||
#define ES_FIELD(x) #x,(int)&((entity_state_t*)0)->x
|
||||
#define CM_FIELD(x) #x,(int)&((usercmd_t*)0)->x
|
||||
|
@ -126,26 +119,20 @@ static const net_desc_t NWDesc[] =
|
|||
// config strings are a general means of communication from
|
||||
// the server to all connected clients.
|
||||
// each config string can be at most MAX_QPATH characters.
|
||||
#define CS_NAME 0
|
||||
#define CS_SKY 1
|
||||
#define CS_SKYAXIS 2 // %f %f %f format
|
||||
#define CS_SKYROTATE 3
|
||||
#define CS_STATUSBAR 4 // hud_program section name
|
||||
#define CS_AIRACCEL 5 // air acceleration control
|
||||
#define CS_MAXCLIENTS 6
|
||||
#define CS_MAPCHECKSUM 7 // for catching cheater maps
|
||||
#define CS_NAME 0 // map name
|
||||
#define CS_MAPCHECKSUM 1 // level checksum (for catching cheater maps)
|
||||
#define CS_SKYNAME 2 // skybox name
|
||||
#define CS_SKYANGLES 3 // <angles> %f %f %f
|
||||
#define CS_SKYSPEED 4 // <speed> %f
|
||||
#define CS_MAXCLIENTS 5 // server maxclients value (0-255)
|
||||
|
||||
// reserved config strings
|
||||
|
||||
#define CS_MODELS 16
|
||||
#define CS_SOUNDS (CS_MODELS+MAX_MODELS)
|
||||
#define CS_IMAGES (CS_SOUNDS+MAX_SOUNDS)
|
||||
#define CS_LIGHTS (CS_IMAGES+MAX_IMAGES)
|
||||
#define CS_DECALS (CS_LIGHTS+MAX_LIGHTSTYLES)
|
||||
#define CS_ITEMS (CS_DECALS+MAX_DECALS)
|
||||
#define CS_PLAYERSKINS (CS_ITEMS+MAX_ITEMS)
|
||||
#define CS_GENERAL (CS_PLAYERSKINS+MAX_CLIENTS)
|
||||
#define MAX_CONFIGSTRINGS (CS_GENERAL+MAX_GENERAL)
|
||||
#define CS_MODELS 16 // configstrings starts here
|
||||
#define CS_SOUNDS (CS_MODELS+MAX_MODELS) // sound names
|
||||
#define CS_CLASSNAMES (CS_SOUNDS+MAX_SOUNDS) // edicts classnames
|
||||
#define CS_LIGHTSTYLES (CS_CLASSNAMES+MAX_CLASSNAMES) // lightstyle patterns
|
||||
#define MAX_CONFIGSTRINGS (CS_LIGHTSTYLES+MAX_LIGHTSTYLES) // total count
|
||||
|
||||
// sound flags (get rid of this)
|
||||
#define SND_VOL (1<<0) // a scaled byte
|
||||
|
@ -208,8 +195,7 @@ void MSG_ReadPos( sizebuf_t *sb, vec3_t pos );
|
|||
void MSG_ReadData( sizebuf_t *sb, void *buffer, size_t size );
|
||||
void MSG_ReadDeltaUsercmd( sizebuf_t *sb, usercmd_t *from, usercmd_t *cmd );
|
||||
void MSG_ReadDeltaEntity( sizebuf_t *sb, entity_state_t *from, entity_state_t *to, int number );
|
||||
void MSG_WriteDeltaPlayerstate( entity_state_t *from, entity_state_t *to, sizebuf_t *msg );
|
||||
void MSG_ReadDeltaPlayerstate( sizebuf_t *msg, entity_state_t *from, entity_state_t *to );
|
||||
entity_state_t MSG_ParseDeltaPlayer( entity_state_t *from, entity_state_t *to );
|
||||
|
||||
// huffman compression
|
||||
void Huff_Init( void );
|
||||
|
|
|
@ -126,7 +126,7 @@ SOURCE=.\client\cl_demo.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_ents.c
|
||||
SOURCE=.\client\cl_frame.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
|
|
|
@ -56,8 +56,7 @@ typedef enum
|
|||
{
|
||||
ss_dead, // no map loaded
|
||||
ss_loading, // spawning level edicts
|
||||
ss_active, // actively running
|
||||
ss_cinematic
|
||||
ss_active // actively running
|
||||
} sv_state_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -79,7 +78,7 @@ typedef struct server_s
|
|||
float frametime;
|
||||
int framenum;
|
||||
|
||||
char name[MAX_QPATH]; // map name, or cinematic name
|
||||
string name; // map name, or cinematic name
|
||||
cmodel_t *models[MAX_MODELS];
|
||||
cmodel_t *worldmodel;
|
||||
|
||||
|
@ -98,14 +97,14 @@ typedef struct server_s
|
|||
|
||||
typedef struct
|
||||
{
|
||||
entity_state_t ps;
|
||||
int areabytes;
|
||||
byte areabits[MAX_MAP_AREAS/8]; // portalarea visibility bits
|
||||
int areabits_size;
|
||||
int num_entities;
|
||||
int first_entity; // into the circular sv_packet_entities[]
|
||||
int msg_sent; // time the message was transmitted
|
||||
int msg_size; // used to rate drop packets
|
||||
int latency; // message latency time
|
||||
int index; // client edict index
|
||||
} client_frame_t;
|
||||
|
||||
typedef struct sv_client_s
|
||||
|
@ -274,8 +273,7 @@ void SV_DropClient (sv_client_t *drop);
|
|||
|
||||
int SV_ModelIndex (const char *name);
|
||||
int SV_SoundIndex (const char *name);
|
||||
int SV_ImageIndex (const char *name);
|
||||
int SV_DecalIndex (const char *name);
|
||||
int SV_ClassIndex (const char *name);
|
||||
|
||||
void SV_WriteClientdataToMessage (sv_client_t *client, sizebuf_t *msg);
|
||||
void SV_ExecuteUserCommand (char *s);
|
||||
|
@ -290,8 +288,8 @@ void Master_Packet (void);
|
|||
// sv_init.c
|
||||
//
|
||||
void SV_InitGame (void);
|
||||
void SV_Map(char *levelstring, char *savename );
|
||||
void SV_SpawnServer (char *server, char *savename, sv_state_t serverstate );
|
||||
void SV_Map( char *levelstring, char *savename );
|
||||
void SV_SpawnServer( const char *server, const char *savename );
|
||||
int SV_FindIndex (const char *name, int start, int end, bool create);
|
||||
void SV_VM_Begin(void);
|
||||
void SV_VM_End(void);
|
||||
|
@ -303,6 +301,7 @@ void SV_Physics( void );
|
|||
void SV_PlayerMove( sv_edict_t *ed );
|
||||
void SV_DropToFloor (edict_t *ent);
|
||||
void SV_CheckGround (edict_t *ent);
|
||||
bool SV_UnstickEntity( edict_t *ent );
|
||||
int SV_ContentsMask( const edict_t *passedict );
|
||||
bool SV_MoveStep (edict_t *ent, vec3_t move, bool relink);
|
||||
void SV_Physics_ClientMove( sv_client_t *cl, usercmd_t *cmd );
|
||||
|
@ -392,7 +391,7 @@ void SV_TouchTriggers (edict_t *ent);
|
|||
//
|
||||
void SV_WriteSaveFile( char *name );
|
||||
void SV_ReadSaveFile( char *name );
|
||||
void SV_ReadLevelFile( char *name );
|
||||
void SV_ReadLevelFile( const char *name );
|
||||
//============================================================
|
||||
|
||||
//
|
||||
|
|
|
@ -223,6 +223,7 @@ bool SV_ClientConnect( edict_t *ent, char *userinfo )
|
|||
|
||||
// make sure we start with known default
|
||||
ent->progs.sv->flags = 0;
|
||||
ent->progs.sv->aiflags = 0;
|
||||
|
||||
MsgDev(D_NOTE, "SV_ClientConnect()\n");
|
||||
prog->globals.sv->time = sv.time;
|
||||
|
@ -480,6 +481,7 @@ void SV_PutClientInServer( edict_t *ent )
|
|||
{
|
||||
int index;
|
||||
sv_client_t *client;
|
||||
edict_t *viewmodel;
|
||||
int i;
|
||||
|
||||
index = PRVM_NUM_FOR_EDICT( ent ) - 1;
|
||||
|
@ -499,18 +501,42 @@ void SV_PutClientInServer( edict_t *ent )
|
|||
ent->progs.sv->v_angle[ROLL] = 0; // cut off any camera rolling
|
||||
ent->progs.sv->origin[2] += 1; // make sure off ground
|
||||
VectorCopy( ent->progs.sv->origin, ent->progs.sv->old_origin );
|
||||
|
||||
// create viewmodel
|
||||
viewmodel = PRVM_ED_Alloc();
|
||||
viewmodel->progs.sv->classname = PRVM_SetEngineString( "viewmodel" );
|
||||
VectorCopy( ent->progs.sv->view_ofs, viewmodel->progs.sv->view_ofs );
|
||||
VectorCopy( ent->progs.sv->origin, viewmodel->progs.sv->origin );
|
||||
VectorCopy( ent->progs.sv->angles, viewmodel->progs.sv->angles );
|
||||
viewmodel->progs.sv->model = ent->progs.sv->v_model;
|
||||
|
||||
// make cross links for consistency
|
||||
viewmodel->progs.sv->aiment = PRVM_NUM_FOR_EDICT( ent );
|
||||
ent->progs.sv->aiment = PRVM_NUM_FOR_EDICT( viewmodel );
|
||||
|
||||
// setup viewflags
|
||||
viewmodel->progs.sv->renderfx = RF_MINLIGHT | RF_DEPTHHACK | RF_VIEWMODEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// restore viewmodel
|
||||
viewmodel = PRVM_EDICT_NUM( ent->progs.sv->aiment );
|
||||
}
|
||||
|
||||
ent->priv.sv->s.fov = 90; // FIXME: get from qc
|
||||
ent->priv.sv->s.fov = bound(1, ent->priv.sv->s.fov, 160);
|
||||
ent->priv.sv->s.health = ent->progs.sv->health;
|
||||
ent->priv.sv->s.vmodel.index = SV_ModelIndex(PRVM_GetString(ent->progs.sv->v_model));
|
||||
ent->priv.sv->s.pmodel.index = SV_ModelIndex(PRVM_GetString(ent->progs.sv->p_model));
|
||||
//ent->priv.sv->s.classname = SV_ClassIndex(PRVM_GetString( ent->progs.sv->classname ));
|
||||
ent->priv.sv->s.pmodel.index = SV_ModelIndex(PRVM_GetString( ent->progs.sv->p_model));
|
||||
VectorCopy( ent->progs.sv->origin, ent->priv.sv->s.origin );
|
||||
VectorCopy( ent->progs.sv->v_angle, ent->priv.sv->s.viewangles );
|
||||
for( i = 0; i < 3; i++ ) ent->priv.sv->s.delta_angles[i] = ANGLE2SHORT(ent->progs.sv->v_angle[i]);
|
||||
viewmodel->priv.sv->s.ed_type = ED_VIEWMODEL; // set entity type
|
||||
viewmodel->progs.sv->modelindex = SV_ModelIndex(PRVM_GetString(viewmodel->progs.sv->model));
|
||||
//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
|
||||
//SV_LinkEdict( viewmodel );
|
||||
ent->priv.sv->physbody = pe->CreatePlayer( ent->priv.sv, SV_GetModelPtr( ent ), ent->progs.sv->m_pmatrix );
|
||||
}
|
||||
|
||||
|
@ -546,9 +572,6 @@ void SV_New_f( sv_client_t *cl )
|
|||
MSG_WriteByte( &cl->netchan.message, svc_serverdata );
|
||||
MSG_WriteLong( &cl->netchan.message, PROTOCOL_VERSION);
|
||||
MSG_WriteLong( &cl->netchan.message, svs.spawncount );
|
||||
|
||||
if( sv.state == ss_cinematic ) playernum = -1;
|
||||
else playernum = sv_client - svs.clients;
|
||||
MSG_WriteShort( &cl->netchan.message, playernum );
|
||||
MSG_WriteString( &cl->netchan.message, sv.configstrings[CS_NAME] );
|
||||
|
||||
|
@ -1033,6 +1056,14 @@ void SV_ApplyClientMove( sv_client_t *cl, usercmd_t *cmd )
|
|||
else if( ent->priv.sv->s.viewangles[PITCH] < 271 && ent->priv.sv->s.viewangles[PITCH] >= 180 )
|
||||
ent->priv.sv->s.viewangles[PITCH] = 271;
|
||||
|
||||
// test
|
||||
if((int)ent->progs.sv->aiflags & AI_DUCKED )
|
||||
{
|
||||
cmd->forwardmove *= 0.333;
|
||||
cmd->sidemove *= 0.333;
|
||||
cmd->upmove *= 0.333;
|
||||
}
|
||||
|
||||
VectorCopy( ent->priv.sv->s.viewangles, cl->edict->progs.sv->v_angle );
|
||||
VectorCopy( ent->priv.sv->s.viewangles, cl->edict->progs.sv->angles );
|
||||
VectorCopy( ent->progs.sv->view_ofs, cl->edict->priv.sv->s.viewoffset );
|
||||
|
@ -1287,7 +1318,7 @@ void SV_ClientThink( sv_client_t *cl, usercmd_t *cmd )
|
|||
// may have been kicked during the last usercmd
|
||||
if( sv_paused->integer ) return;
|
||||
|
||||
SV_ApplyClientMove( cl, cmd );
|
||||
SV_ApplyClientMove( cl, &cl->cmd );
|
||||
// make sure the velocity is sane (not a NaN)
|
||||
SV_CheckVelocity( cl->edict );
|
||||
|
||||
|
|
|
@ -208,43 +208,13 @@ void SV_Map_f( void )
|
|||
|
||||
SV_BroadcastCommand( "changing\n" );
|
||||
SV_SendClientMessages();
|
||||
SV_SpawnServer( filename, NULL, ss_active );
|
||||
SV_SpawnServer( filename, NULL );
|
||||
SV_BroadcastCommand( "reconnect\n" );
|
||||
|
||||
// archive server state
|
||||
com.strncpy( svs.mapcmd, filename, sizeof(svs.mapcmd) - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_Movie_f
|
||||
|
||||
Playing a Darkplaces video with specified name
|
||||
==================
|
||||
*/
|
||||
void SV_Movie_f( void )
|
||||
{
|
||||
char filename[MAX_QPATH];
|
||||
|
||||
if(Cmd_Argc() != 2)
|
||||
{
|
||||
Msg("Usage: movie <filename>\n");
|
||||
return;
|
||||
}
|
||||
|
||||
com.snprintf( filename, MAX_QPATH, "%s.dpv", Cmd_Argv(1));
|
||||
if(!FS_FileExists(va("video/%s", filename )))
|
||||
{
|
||||
Msg("Can't loading %s\n", filename );
|
||||
return;
|
||||
}
|
||||
|
||||
SV_InitGame();
|
||||
SV_BroadcastCommand( "changing\n" );
|
||||
SV_SpawnServer( filename, NULL, ss_cinematic );
|
||||
SV_BroadcastCommand( "reconnect\n" );
|
||||
}
|
||||
|
||||
void SV_Newgame_f( void )
|
||||
{
|
||||
// FIXME: do some clear operations
|
||||
|
@ -277,7 +247,7 @@ void SV_Load_f( void )
|
|||
|
||||
SV_ReadSaveFile( filename );
|
||||
SV_BroadcastCommand( "changing\n" );
|
||||
SV_SpawnServer( svs.mapcmd, filename, ss_active );
|
||||
SV_SpawnServer( svs.mapcmd, filename );
|
||||
SV_BroadcastCommand( "reconnect\n" );
|
||||
}
|
||||
|
||||
|
@ -351,7 +321,7 @@ void SV_ChangeLevel_f( void )
|
|||
SV_InitGame(); // reset previous state
|
||||
SV_BroadcastCommand("changing\n");
|
||||
SV_SendClientMessages();
|
||||
SV_SpawnServer( filename, NULL, ss_active );
|
||||
SV_SpawnServer( filename, NULL );
|
||||
SV_BroadcastCommand ("reconnect\n");
|
||||
|
||||
// archive server state
|
||||
|
@ -542,7 +512,7 @@ Kick everyone off, possibly in preparation for a new game
|
|||
*/
|
||||
void SV_KillServer_f (void)
|
||||
{
|
||||
if(!svs.initialized) return;
|
||||
if( !svs.initialized ) return;
|
||||
com.strncpy( host.finalmsg, "Server was killed\n", MAX_STRING );
|
||||
SV_Shutdown( false );
|
||||
}
|
||||
|
@ -562,7 +532,6 @@ void SV_InitOperatorCommands( void )
|
|||
|
||||
Cmd_AddCommand("map", SV_Map_f, "start new level" );
|
||||
Cmd_AddCommand("newgame", SV_Newgame_f, "begin new game" );
|
||||
Cmd_AddCommand("movie", SV_Movie_f, "playing video file" );
|
||||
Cmd_AddCommand("changelevel", SV_ChangeLevel_f, "changing level" );
|
||||
Cmd_AddCommand("restart", SV_Restart_f, "restarting current level" );
|
||||
Cmd_AddCommand("sectorlist", SV_SectorList_f, "display pvs sectors" );
|
||||
|
|
|
@ -88,31 +88,30 @@ struct sv_entvars_s
|
|||
float watertype;
|
||||
float ltime;
|
||||
string_t model;
|
||||
float body;
|
||||
float skin;
|
||||
float body;
|
||||
float alpha;
|
||||
float frame;
|
||||
float speed;
|
||||
float sequence;
|
||||
float animtime;
|
||||
float sequence;
|
||||
float effects;
|
||||
float colormap;
|
||||
float renderfx;
|
||||
float flags;
|
||||
float aiflags;
|
||||
float spawnflags;
|
||||
vec3_t punchangle;
|
||||
vec3_t view_ofs;
|
||||
vec3_t v_angle;
|
||||
float button0;
|
||||
float button1;
|
||||
float button2;
|
||||
float impulse;
|
||||
vec3_t punchangle;
|
||||
string_t v_model;
|
||||
float v_frame;
|
||||
float v_body;
|
||||
float v_skin;
|
||||
vec3_t v_offset;
|
||||
vec3_t v_angles;
|
||||
float v_sequence;
|
||||
string_t p_model;
|
||||
float p_frame;
|
||||
|
@ -144,106 +143,108 @@ struct sv_entvars_s
|
|||
|
||||
static fields_t sv_reqfields[] =
|
||||
{
|
||||
{149, 6, "walk"},
|
||||
{150, 6, "jump"},
|
||||
{151, 6, "duck"},
|
||||
{152, 2, "v_animtime"},
|
||||
{153, 2, "weapon"},
|
||||
{154, 2, "items"},
|
||||
{155, 1, "target"},
|
||||
{156, 1, "parent"},
|
||||
{157, 1, "targetname"},
|
||||
{158, 2, "deadflag"},
|
||||
{159, 2, "idealpitch"},
|
||||
{160, 1, "netname"},
|
||||
{161, 2, "max_health"},
|
||||
{162, 2, "armortype"},
|
||||
{163, 2, "armorvalue"},
|
||||
{164, 2, "dmg_take"},
|
||||
{165, 2, "dmg_save"},
|
||||
{166, 4, "dmg_inflictor"},
|
||||
{167, 1, "message"},
|
||||
{168, 2, "sounds"},
|
||||
{169, 1, "noise"},
|
||||
{170, 1, "noise1"},
|
||||
{171, 1, "noise2"},
|
||||
{172, 1, "noise3"},
|
||||
{173, 2, "jumpup"},
|
||||
{174, 2, "jumpdn"},
|
||||
{175, 4, "movetarget"},
|
||||
{176, 2, "density"},
|
||||
{177, 2, "dmg"},
|
||||
{178, 2, "dmgtime"},
|
||||
{179, 6, "th_stand"},
|
||||
{180, 6, "th_walk"},
|
||||
{181, 6, "th_run"},
|
||||
{182, 6, "th_pain"},
|
||||
{183, 6, "th_die"},
|
||||
{184, 6, "th_missile"},
|
||||
{185, 6, "th_melee"},
|
||||
{186, 2, "walkframe"},
|
||||
{187, 2, "attack_finished"},
|
||||
{188, 2, "pain_finished"},
|
||||
{189, 2, "invincible_finished"},
|
||||
{190, 2, "invisible_finished"},
|
||||
{191, 2, "super_damage_finished"},
|
||||
{192, 2, "radsuit_finished"},
|
||||
{193, 2, "invincible_time"},
|
||||
{194, 2, "invincible_sound"},
|
||||
{195, 2, "invisible_time"},
|
||||
{196, 2, "invisible_sound"},
|
||||
{197, 2, "super_time"},
|
||||
{198, 2, "super_sound"},
|
||||
{199, 2, "rad_time"},
|
||||
{200, 2, "fly_sound"},
|
||||
{201, 1, "wad"},
|
||||
{202, 1, "map"},
|
||||
{203, 1, "landmark"},
|
||||
{204, 2, "worldtype"},
|
||||
{205, 2, "delay"},
|
||||
{206, 2, "wait"},
|
||||
{207, 2, "lip"},
|
||||
{208, 2, "light_lev"},
|
||||
{209, 2, "style"},
|
||||
{210, 2, "skill"},
|
||||
{211, 1, "killtarget"},
|
||||
{212, 1, "noise4"},
|
||||
{213, 3, "pos1"},
|
||||
{216, 3, "pos2"},
|
||||
{219, 3, "mangle"},
|
||||
{222, 2, "count"},
|
||||
{223, 6, "movedone"},
|
||||
{224, 3, "finaldest"},
|
||||
{227, 3, "finalangle"},
|
||||
{230, 2, "t_length"},
|
||||
{231, 2, "t_width"},
|
||||
{232, 3, "dest"},
|
||||
{235, 3, "dest1"},
|
||||
{238, 3, "dest2"},
|
||||
{241, 2, "state"},
|
||||
{242, 2, "height"},
|
||||
{243, 2, "cnt"},
|
||||
{244, 2, "air_finished"},
|
||||
{245, 3, "camview"},
|
||||
{248, 2, "aflag"},
|
||||
{249, 4, "trigger_field"},
|
||||
{250, 2, "m_fSequenceLoops"},
|
||||
{251, 2, "m_fSequenceFinished"},
|
||||
{252, 2, "framerate"},
|
||||
{253, 2, "anim_time"},
|
||||
{254, 2, "anim_end"},
|
||||
{255, 2, "anim_priority"},
|
||||
{256, 2, "anim_run"},
|
||||
{257, 2, "showhelp"},
|
||||
{258, 2, "showinventory"},
|
||||
{259, 2, "touched"},
|
||||
{260, 1, "name"},
|
||||
{261, 4, "triggerer"},
|
||||
{262, 2, "used"},
|
||||
{263, 1, "target_dest"},
|
||||
{264, 1, "oldmodel"}
|
||||
{144, 6, "walk"},
|
||||
{145, 6, "jump"},
|
||||
{146, 6, "duck"},
|
||||
{147, 2, "jump_flag"},
|
||||
{148, 2, "swim_flag"},
|
||||
{149, 2, "v_animtime"},
|
||||
{150, 2, "weapon"},
|
||||
{151, 2, "items"},
|
||||
{152, 1, "target"},
|
||||
{153, 1, "parent"},
|
||||
{154, 1, "targetname"},
|
||||
{155, 2, "deadflag"},
|
||||
{156, 2, "idealpitch"},
|
||||
{157, 1, "netname"},
|
||||
{158, 2, "max_health"},
|
||||
{159, 2, "armortype"},
|
||||
{160, 2, "armorvalue"},
|
||||
{161, 2, "dmg_take"},
|
||||
{162, 2, "dmg_save"},
|
||||
{163, 4, "dmg_inflictor"},
|
||||
{164, 1, "message"},
|
||||
{165, 2, "sounds"},
|
||||
{166, 1, "noise"},
|
||||
{167, 1, "noise1"},
|
||||
{168, 1, "noise2"},
|
||||
{169, 1, "noise3"},
|
||||
{170, 2, "jumpup"},
|
||||
{171, 2, "jumpdn"},
|
||||
{172, 4, "movetarget"},
|
||||
{173, 2, "density"},
|
||||
{174, 2, "dmg"},
|
||||
{175, 2, "dmgtime"},
|
||||
{176, 6, "th_stand"},
|
||||
{177, 6, "th_walk"},
|
||||
{178, 6, "th_run"},
|
||||
{179, 6, "th_pain"},
|
||||
{180, 6, "th_die"},
|
||||
{181, 6, "th_missile"},
|
||||
{182, 6, "th_melee"},
|
||||
{183, 2, "walkframe"},
|
||||
{184, 2, "attack_finished"},
|
||||
{185, 2, "pain_finished"},
|
||||
{186, 2, "invincible_finished"},
|
||||
{187, 2, "invisible_finished"},
|
||||
{188, 2, "super_damage_finished"},
|
||||
{189, 2, "radsuit_finished"},
|
||||
{190, 2, "invincible_time"},
|
||||
{191, 2, "invincible_sound"},
|
||||
{192, 2, "invisible_time"},
|
||||
{193, 2, "invisible_sound"},
|
||||
{194, 2, "super_time"},
|
||||
{195, 2, "super_sound"},
|
||||
{196, 2, "rad_time"},
|
||||
{197, 2, "fly_sound"},
|
||||
{198, 1, "wad"},
|
||||
{199, 1, "map"},
|
||||
{200, 1, "landmark"},
|
||||
{201, 2, "worldtype"},
|
||||
{202, 2, "delay"},
|
||||
{203, 2, "wait"},
|
||||
{204, 2, "lip"},
|
||||
{205, 2, "light_lev"},
|
||||
{206, 2, "style"},
|
||||
{207, 2, "skill"},
|
||||
{208, 1, "killtarget"},
|
||||
{209, 1, "noise4"},
|
||||
{210, 3, "pos1"},
|
||||
{213, 3, "pos2"},
|
||||
{216, 3, "mangle"},
|
||||
{219, 2, "count"},
|
||||
{220, 6, "movedone"},
|
||||
{221, 3, "finaldest"},
|
||||
{224, 3, "finalangle"},
|
||||
{227, 2, "t_length"},
|
||||
{228, 2, "t_width"},
|
||||
{229, 3, "dest"},
|
||||
{232, 3, "dest1"},
|
||||
{235, 3, "dest2"},
|
||||
{238, 2, "state"},
|
||||
{239, 2, "height"},
|
||||
{240, 2, "cnt"},
|
||||
{241, 2, "air_finished"},
|
||||
{242, 3, "camview"},
|
||||
{245, 2, "aflag"},
|
||||
{246, 4, "trigger_field"},
|
||||
{247, 2, "m_fSequenceLoops"},
|
||||
{248, 2, "m_fSequenceFinished"},
|
||||
{249, 2, "framerate"},
|
||||
{250, 2, "anim_time"},
|
||||
{251, 2, "anim_end"},
|
||||
{252, 2, "anim_priority"},
|
||||
{253, 2, "anim_run"},
|
||||
{254, 2, "showhelp"},
|
||||
{255, 2, "showinventory"},
|
||||
{256, 2, "touched"},
|
||||
{257, 1, "name"},
|
||||
{258, 4, "triggerer"},
|
||||
{259, 2, "used"},
|
||||
{260, 1, "target_dest"},
|
||||
{261, 1, "oldmodel"}
|
||||
};
|
||||
|
||||
#define PROG_CRC_SERVER 61861
|
||||
#define PROG_CRC_SERVER 1476
|
||||
|
||||
#endif//SV_EDICT_H
|
|
@ -7,6 +7,9 @@
|
|||
#include "server.h"
|
||||
|
||||
static byte fatpvs[MAX_MAP_LEAFS/8];
|
||||
static byte *clientpvs;
|
||||
static byte *clientphs;
|
||||
static byte *bitvector;
|
||||
|
||||
/*
|
||||
============
|
||||
|
@ -63,6 +66,8 @@ Copy PRVM values into entity state
|
|||
*/
|
||||
void SV_UpdateEntityState( edict_t *ent )
|
||||
{
|
||||
edict_t *client;
|
||||
|
||||
// copy progs values to state
|
||||
ent->priv.sv->s.number = ent->priv.sv->serialnumber;
|
||||
ent->priv.sv->s.solid = ent->priv.sv->solid;
|
||||
|
@ -80,12 +85,103 @@ void SV_UpdateEntityState( edict_t *ent )
|
|||
ent->priv.sv->s.renderfx = (int)ent->progs.sv->renderfx; // renderer flags
|
||||
ent->priv.sv->s.renderamt = ent->progs.sv->alpha; // alpha value
|
||||
ent->priv.sv->s.model.animtime = ent->progs.sv->animtime; // auto-animating time
|
||||
ent->priv.sv->s.aiment = ent->progs.sv->aiment; // viewmodel parent
|
||||
|
||||
// copy viewmodel info
|
||||
ent->priv.sv->s.vmodel.frame = ent->progs.sv->v_frame;
|
||||
ent->priv.sv->s.vmodel.body = ent->progs.sv->v_body;
|
||||
ent->priv.sv->s.vmodel.skin = ent->progs.sv->v_skin;
|
||||
ent->priv.sv->s.vmodel.sequence = ent->progs.sv->v_sequence;
|
||||
if( ent->priv.sv->s.ed_type == ED_VIEWMODEL )
|
||||
{
|
||||
// copy v_model state from client to viemodel entity
|
||||
client = PRVM_EDICT_NUM( ent->progs.sv->aiment );
|
||||
|
||||
// update both arrays, because viewmodel are hidden for qc-coders
|
||||
ent->priv.sv->s.model.index = ent->progs.sv->modelindex = SV_ModelIndex(PRVM_GetString(client->progs.sv->v_model));
|
||||
ent->priv.sv->s.model.frame = ent->progs.sv->frame = client->progs.sv->v_frame;
|
||||
ent->priv.sv->s.model.body = ent->progs.sv->body = client->progs.sv->v_body;
|
||||
ent->priv.sv->s.model.skin = ent->progs.sv->skin = client->progs.sv->v_skin;
|
||||
ent->priv.sv->s.model.sequence = ent->progs.sv->sequence = client->progs.sv->v_sequence;
|
||||
VectorCopy( ent->progs.sv->origin, ent->priv.sv->s.old_origin );
|
||||
ent->priv.sv->s.model.colormap = ent->progs.sv->colormap = client->progs.sv->colormap;
|
||||
}
|
||||
}
|
||||
|
||||
bool SV_EdictNeedsUpdate( edict_t *ent, edict_t *clent, int clientarea )
|
||||
{
|
||||
int i, l;
|
||||
|
||||
// send viewmodel entity always
|
||||
// NOTE: never apply LinkEdict to viewmodel entity, because
|
||||
// we wan't see it in list of entities returned with SV_AreaEdicts
|
||||
if( ent->priv.sv->s.ed_type == ED_VIEWMODEL )
|
||||
return true;
|
||||
|
||||
// ignore if not touching a PV leaf
|
||||
if( ent != clent )
|
||||
{
|
||||
// check area
|
||||
if( !pe->AreasConnected( clientarea, ent->priv.sv->areanum ))
|
||||
{
|
||||
// doors can legally straddle two areas, so
|
||||
// we may need to check another one
|
||||
int areanum2 = ent->priv.sv->areanum2;
|
||||
if( !areanum2 || !pe->AreasConnected( clientarea, areanum2 ))
|
||||
return false; // blocked by a door
|
||||
}
|
||||
|
||||
// FIXME: if an ent has a model and a sound, but isn't
|
||||
// in the PVS, only the PHS, clear the model
|
||||
if( ent->priv.sv->s.soundindex ) bitvector = clientphs;
|
||||
else if( sv_fatpvs->integer ) bitvector = fatpvs;
|
||||
else bitvector = clientpvs;
|
||||
|
||||
// check individual leafs
|
||||
if( !ent->priv.sv->num_clusters ) return false;
|
||||
for( i = 0, l = 0; i < ent->priv.sv->num_clusters; i++ )
|
||||
{
|
||||
l = ent->priv.sv->clusternums[i];
|
||||
if( bitvector[l>>3] & (1<<(l&7)))
|
||||
break;
|
||||
}
|
||||
|
||||
// if we haven't found it to be visible,
|
||||
// check overflow clusters that coudln't be stored
|
||||
if( i == ent->priv.sv->num_clusters )
|
||||
{
|
||||
if( ent->priv.sv->lastcluster )
|
||||
{
|
||||
for( ; l <= ent->priv.sv->lastcluster; l++ )
|
||||
{
|
||||
if( bitvector[l>>3] & (1<<(l&7)))
|
||||
break;
|
||||
}
|
||||
if( l == ent->priv.sv->lastcluster )
|
||||
return false; // not visible
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
if( !ent->progs.sv->modelindex )
|
||||
{
|
||||
// don't send sounds if they will be attenuated away
|
||||
vec3_t org, delta, entorigin;
|
||||
float len;
|
||||
|
||||
if(VectorIsNull( ent->progs.sv->origin ))
|
||||
{
|
||||
VectorAdd( ent->progs.sv->mins, ent->progs.sv->maxs, entorigin );
|
||||
VectorScale( entorigin, 0.5, entorigin );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( ent->progs.sv->origin, entorigin );
|
||||
}
|
||||
|
||||
VectorCopy( clent->priv.sv->s.origin, org );
|
||||
VectorAdd( org, clent->priv.sv->s.viewoffset, org );
|
||||
VectorSubtract( org, entorigin, delta );
|
||||
len = VectorLength( delta );
|
||||
if( len > 400 ) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -199,11 +295,14 @@ void SV_WriteFrameToClient( sv_client_t *cl, sizebuf_t *msg )
|
|||
cl->surpressCount = 0;
|
||||
|
||||
// send over the areabits
|
||||
MSG_WriteByte( msg, frame->areabytes );
|
||||
MSG_WriteData( msg, frame->areabits, frame->areabytes );
|
||||
MSG_WriteByte( msg, frame->areabits_size );
|
||||
MSG_WriteData( msg, frame->areabits, frame->areabits_size );
|
||||
|
||||
// delta encode the playerstate
|
||||
MSG_WriteDeltaPlayerstate( &oldframe->ps, &frame->ps, msg );
|
||||
// just send an client index
|
||||
// it's safe, because PRVM_NUM_FOR_EDICT always equal ed->serialnumber,
|
||||
// thats shared across network
|
||||
MSG_WriteByte( msg, svc_clientindex );
|
||||
MSG_WriteByte( msg, frame->index );
|
||||
|
||||
// delta encode the entities
|
||||
SV_EmitPacketEntities( oldframe, frame, msg );
|
||||
|
@ -227,18 +326,14 @@ copies off the playerstat and areabits.
|
|||
*/
|
||||
void SV_BuildClientFrame( sv_client_t *cl )
|
||||
{
|
||||
int i, e, l;
|
||||
vec3_t org;
|
||||
edict_t *ent;
|
||||
edict_t *clent;
|
||||
client_frame_t *frame;
|
||||
entity_state_t *state;
|
||||
int clientarea;
|
||||
int e, clientarea;
|
||||
int clientcluster;
|
||||
int leafnum;
|
||||
byte *clientpvs;
|
||||
byte *clientphs;
|
||||
byte *bitvector;
|
||||
|
||||
clent = cl->edict;
|
||||
if( !clent->priv.sv->client )
|
||||
|
@ -261,10 +356,10 @@ void SV_BuildClientFrame( sv_client_t *cl )
|
|||
clientcluster = pe->LeafCluster( leafnum );
|
||||
|
||||
// calculate the visible areas
|
||||
frame->areabytes = pe->WriteAreaBits( frame->areabits, clientarea );
|
||||
frame->areabits_size = pe->WriteAreaBits( frame->areabits, clientarea );
|
||||
|
||||
// grab the current player state
|
||||
frame->ps = clent->priv.sv->s;
|
||||
// grab the current player index
|
||||
frame->index = PRVM_NUM_FOR_EDICT( clent );
|
||||
|
||||
clientpvs = pe->ClusterPVS( clientcluster );
|
||||
clientphs = pe->ClusterPHS( clientcluster );
|
||||
|
@ -281,74 +376,12 @@ void SV_BuildClientFrame( sv_client_t *cl )
|
|||
if( !ent->progs.sv->modelindex && !ent->progs.sv->effects && !ent->priv.sv->s.soundindex )
|
||||
continue;
|
||||
|
||||
// ignore if not touching a PV leaf
|
||||
if( ent != clent )
|
||||
{
|
||||
// check area
|
||||
if( !pe->AreasConnected( clientarea, ent->priv.sv->areanum ))
|
||||
{
|
||||
// doors can legally straddle two areas, so
|
||||
// we may need to check another one
|
||||
int areanum2 = ent->priv.sv->areanum2;
|
||||
if( !areanum2 || !pe->AreasConnected( clientarea, areanum2 ))
|
||||
continue; // blocked by a door
|
||||
}
|
||||
|
||||
// FIXME: if an ent has a model and a sound, but isn't
|
||||
// in the PVS, only the PHS, clear the model
|
||||
if( ent->priv.sv->s.soundindex ) bitvector = clientphs;
|
||||
else if( sv_fatpvs->integer ) bitvector = fatpvs;
|
||||
else bitvector = clientpvs;
|
||||
|
||||
// check individual leafs
|
||||
if( !ent->priv.sv->num_clusters ) continue;
|
||||
for( i = 0, l = 0; i < ent->priv.sv->num_clusters; i++ )
|
||||
{
|
||||
l = ent->priv.sv->clusternums[i];
|
||||
if( bitvector[l>>3] & (1<<(l&7)))
|
||||
break;
|
||||
}
|
||||
// if we haven't found it to be visible,
|
||||
// check overflow clusters that coudln't be stored
|
||||
if( i == ent->priv.sv->num_clusters )
|
||||
{
|
||||
if( ent->priv.sv->lastcluster )
|
||||
{
|
||||
for( ; l <= ent->priv.sv->lastcluster; l++ )
|
||||
{
|
||||
if( bitvector[l>>3] & (1<<(l&7)))
|
||||
break;
|
||||
}
|
||||
if( l == ent->priv.sv->lastcluster )
|
||||
continue; // not visible
|
||||
}
|
||||
else continue;
|
||||
}
|
||||
if( !ent->progs.sv->modelindex )
|
||||
{
|
||||
// don't send sounds if they will be attenuated away
|
||||
vec3_t delta, entorigin;
|
||||
float len;
|
||||
|
||||
if(VectorIsNull( ent->progs.sv->origin ))
|
||||
{
|
||||
VectorAdd( ent->progs.sv->mins, ent->progs.sv->maxs, entorigin );
|
||||
VectorScale( entorigin, 0.5, entorigin );
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorCopy( ent->progs.sv->origin, entorigin );
|
||||
}
|
||||
|
||||
VectorSubtract( org, entorigin, delta );
|
||||
len = VectorLength( delta );
|
||||
if( len > 400 ) continue;
|
||||
}
|
||||
}
|
||||
if(!SV_EdictNeedsUpdate( ent, clent, clientarea ))
|
||||
continue;
|
||||
|
||||
// add it to the circular client_entities array
|
||||
state = &svs.client_entities[svs.next_client_entities % svs.num_client_entities];
|
||||
if (ent->priv.sv->serialnumber != e)
|
||||
if( ent->priv.sv->serialnumber != e )
|
||||
{
|
||||
MsgDev( D_WARN, "SV_BuildClientFrame: invalid number %d\n", ent->priv.sv->serialnumber );
|
||||
ent->priv.sv->serialnumber = e; // ptr to current entity such as entnumber
|
||||
|
@ -471,11 +504,7 @@ void SV_SendClientMessages( void )
|
|||
SV_DropClient( cl );
|
||||
}
|
||||
|
||||
if( sv.state == ss_cinematic )
|
||||
{
|
||||
Netchan_Transmit( &cl->netchan, 0, NULL );
|
||||
}
|
||||
else if( cl->state == cs_spawned )
|
||||
if( cl->state == cs_spawned )
|
||||
{
|
||||
// don't overrun bandwidth
|
||||
if( SV_RateDrop( cl )) continue;
|
||||
|
|
|
@ -34,14 +34,13 @@ int SV_FindIndex (const char *name, int start, int end, bool create)
|
|||
{
|
||||
int i = 0;
|
||||
|
||||
if (!name || !name[0]) return 0;
|
||||
if(!name || !name[0]) return 0;
|
||||
|
||||
for (i = 1; i < end && sv.configstrings[start+i][0]; i++)
|
||||
for( i = 1; i < end && sv.configstrings[start+i][0]; i++ )
|
||||
if(!com.strcmp(sv.configstrings[start+i], name))
|
||||
return i;
|
||||
if(!create) return 0;
|
||||
|
||||
if (i == end)
|
||||
if( !create ) return 0;
|
||||
if( i == end )
|
||||
{
|
||||
MsgDev( D_WARN, "SV_FindIndex: %d out of range [%d - %d]\n", start, end );
|
||||
return 0;
|
||||
|
@ -50,14 +49,14 @@ int SV_FindIndex (const char *name, int start, int end, bool create)
|
|||
// register new resource
|
||||
com.strncpy (sv.configstrings[start+i], name, sizeof(sv.configstrings[i]));
|
||||
|
||||
if (sv.state != ss_loading)
|
||||
if( sv.state != ss_loading )
|
||||
{
|
||||
// send the update to everyone
|
||||
MSG_Clear( &sv.multicast );
|
||||
MSG_Begin(svc_configstring);
|
||||
MSG_WriteShort (&sv.multicast, start + i);
|
||||
MSG_WriteString (&sv.multicast, (char *)name);
|
||||
MSG_Send(MSG_ALL_R, vec3_origin, NULL );
|
||||
MSG_Begin( svc_configstring );
|
||||
MSG_WriteShort( &sv.multicast, start + i );
|
||||
MSG_WriteString( &sv.multicast, name );
|
||||
MSG_Send( MSG_ALL_R, vec3_origin, NULL );
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
@ -73,16 +72,10 @@ int SV_SoundIndex (const char *name)
|
|||
return SV_FindIndex (name, CS_SOUNDS, MAX_SOUNDS, true);
|
||||
}
|
||||
|
||||
int SV_ImageIndex (const char *name)
|
||||
int SV_ClassIndex( const char *name )
|
||||
{
|
||||
return SV_FindIndex (name, CS_IMAGES, MAX_IMAGES, true);
|
||||
return SV_FindIndex (name, CS_CLASSNAMES, MAX_CLASSNAMES, true);
|
||||
}
|
||||
|
||||
int SV_DecalIndex (const char *name)
|
||||
{
|
||||
return SV_FindIndex (name, CS_DECALS, MAX_DECALS, true);
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
SV_CreateBaseline
|
||||
|
@ -121,7 +114,7 @@ void SV_CreateBaseline (void)
|
|||
SV_CheckForSavegame
|
||||
=================
|
||||
*/
|
||||
void SV_CheckForSavegame (char *savename )
|
||||
void SV_CheckForSavegame( const char *savename )
|
||||
{
|
||||
sv.loadgame = true; // predicting state
|
||||
|
||||
|
@ -142,63 +135,50 @@ clients along with it.
|
|||
|
||||
================
|
||||
*/
|
||||
void SV_SpawnServer( char *server, char *savename, sv_state_t serverstate )
|
||||
void SV_SpawnServer( const char *server, const char *savename )
|
||||
{
|
||||
uint i, checksum;
|
||||
|
||||
if( serverstate == ss_cinematic ) Cvar_Set ("paused", "0");
|
||||
|
||||
Msg("SpawnServer [%s]\n", server );
|
||||
|
||||
svs.spawncount++; // any partially connected client will be restarted
|
||||
sv.state = ss_dead;
|
||||
Host_SetServerState(sv.state);
|
||||
Host_SetServerState( sv.state );
|
||||
|
||||
// wipe the entire per-level structure
|
||||
memset (&sv, 0, sizeof(sv));
|
||||
memset( &sv, 0, sizeof( sv ));
|
||||
svs.realtime = 0;
|
||||
svs.timeleft = 0;
|
||||
|
||||
// save name for levels that don't set message
|
||||
com.strcpy (sv.configstrings[CS_NAME], server);
|
||||
if( Cvar_VariableValue ("deathmatch") )
|
||||
com.sprintf( sv.configstrings[CS_AIRACCEL], "%g", sv_airaccelerate->value );
|
||||
else com.strcpy( sv.configstrings[CS_AIRACCEL], "0" );
|
||||
|
||||
MSG_Init(&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));
|
||||
com.strncpy( sv.configstrings[CS_NAME], server, MAX_QPATH );
|
||||
MSG_Init( &sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));
|
||||
com.strcpy( sv.name, server );
|
||||
|
||||
SV_VM_Begin();
|
||||
|
||||
// leave slots at start for clients only
|
||||
for (i = 0; i < Host_MaxClients(); i++)
|
||||
for( i = 0; i < Host_MaxClients(); i++ )
|
||||
{
|
||||
// needs to reconnect
|
||||
if (svs.clients[i].state > cs_connected)
|
||||
if( svs.clients[i].state > cs_connected )
|
||||
svs.clients[i].state = cs_connected;
|
||||
svs.clients[i].lastframe = -1;
|
||||
}
|
||||
|
||||
sv.time = 1.0f;
|
||||
|
||||
com.strcpy(sv.name, server);
|
||||
com.strncpy( sv.name, server, MAX_STRING );
|
||||
FS_FileBase(server, sv.configstrings[CS_NAME]);
|
||||
|
||||
if (serverstate != ss_active)
|
||||
{
|
||||
sv.worldmodel = sv.models[1] = pe->BeginRegistration( "", false, &checksum); // no real map
|
||||
}
|
||||
else
|
||||
{
|
||||
com.sprintf(sv.configstrings[CS_MODELS+1], "maps/%s", server);
|
||||
sv.worldmodel = sv.models[1] = pe->BeginRegistration(sv.configstrings[CS_MODELS+1], false, &checksum);
|
||||
}
|
||||
com.sprintf(sv.configstrings[CS_MAPCHECKSUM], "%i", checksum);
|
||||
com.sprintf( sv.configstrings[CS_MODELS+1], "maps/%s", server );
|
||||
sv.worldmodel = sv.models[1] = pe->BeginRegistration( sv.configstrings[CS_MODELS+1], false, &checksum );
|
||||
com.sprintf( sv.configstrings[CS_MAPCHECKSUM], "%i", checksum );
|
||||
|
||||
// clear physics interaction links
|
||||
SV_ClearWorld();
|
||||
|
||||
for (i = 1; i < pe->NumBmodels(); i++)
|
||||
for( i = 1; i < pe->NumBmodels(); i++ )
|
||||
{
|
||||
com.sprintf( sv.configstrings[CS_MODELS+1+i], "*%i", i );
|
||||
sv.models[i+1] = pe->RegisterModel(sv.configstrings[CS_MODELS+1+i] );
|
||||
|
@ -216,12 +196,8 @@ void SV_SpawnServer( char *server, char *savename, sv_state_t serverstate )
|
|||
// check for a savegame
|
||||
SV_CheckForSavegame( savename );
|
||||
|
||||
if( serverstate == ss_active )
|
||||
{
|
||||
// ignore ents for cinematic servers
|
||||
if(sv.loadgame) SV_ReadLevelFile( savename );
|
||||
else SV_SpawnEntities( sv.name, pe->GetEntityString());
|
||||
}
|
||||
if( sv.loadgame ) SV_ReadLevelFile( savename );
|
||||
else SV_SpawnEntities( sv.name, pe->GetEntityString());
|
||||
|
||||
// run two frames to allow everything to settle
|
||||
for( i = 0; i < 2; i++ )
|
||||
|
@ -231,11 +207,11 @@ void SV_SpawnServer( char *server, char *savename, sv_state_t serverstate )
|
|||
}
|
||||
|
||||
// all precaches are complete
|
||||
sv.state = serverstate;
|
||||
sv.state = ss_active;
|
||||
Host_SetServerState( sv.state );
|
||||
|
||||
// create a baseline for more efficient communications
|
||||
SV_CreateBaseline ();
|
||||
SV_CreateBaseline();
|
||||
|
||||
// set serverinfo variable
|
||||
Cvar_FullSet("mapname", sv.name, CVAR_SERVERINFO | CVAR_INIT);
|
||||
|
@ -287,10 +263,10 @@ void SV_InitGame( void )
|
|||
// init clients
|
||||
if( Cvar_VariableValue( "deathmatch" ))
|
||||
{
|
||||
if(Host_MaxClients() <= 1)
|
||||
if( Host_MaxClients() <= 1 )
|
||||
Cvar_FullSet( "host_maxclients", "8", CVAR_SERVERINFO|CVAR_LATCH );
|
||||
else if(Host_MaxClients() > MAX_CLIENTS )
|
||||
Cvar_FullSet( "host_maxclients", va("%i", MAX_CLIENTS), CVAR_SERVERINFO|CVAR_LATCH );
|
||||
else if( Host_MaxClients() > 255 )
|
||||
Cvar_FullSet( "host_maxclients", va("%i", 255 ), CVAR_SERVERINFO|CVAR_LATCH );
|
||||
}
|
||||
else if( Cvar_VariableValue( "coop" ))
|
||||
{
|
||||
|
|
|
@ -388,7 +388,7 @@ not just stuck on the outgoing message list, because the server is going
|
|||
to totally exit after returning from this function.
|
||||
==================
|
||||
*/
|
||||
void SV_FinalMessage (char *message, bool reconnect)
|
||||
void SV_FinalMessage( char *message, bool reconnect )
|
||||
{
|
||||
sv_client_t *cl;
|
||||
byte msg_buf[MAX_MSGLEN];
|
||||
|
@ -435,20 +435,20 @@ void SV_Shutdown( bool reconnect )
|
|||
// already freed
|
||||
if(host.state == HOST_ERROR) return;
|
||||
|
||||
MsgDev(D_NOTE, "SV_Shutdown: %s\n", host.finalmsg );
|
||||
if (svs.clients) SV_FinalMessage( host.finalmsg, reconnect);
|
||||
MsgDev( D_INFO, "SV_Shutdown: %s\n", host.finalmsg );
|
||||
if( svs.clients ) SV_FinalMessage( host.finalmsg, reconnect);
|
||||
|
||||
Master_Shutdown();
|
||||
SV_FreeServerProgs();
|
||||
|
||||
// free current level
|
||||
memset (&sv, 0, sizeof(sv));
|
||||
memset( &sv, 0, sizeof( sv ));
|
||||
Host_SetServerState (sv.state);
|
||||
|
||||
// free server static data
|
||||
if( svs.clients ) Mem_Free( svs.clients );
|
||||
if( svs.baselines ) Mem_Free( svs.baselines );
|
||||
if( svs.client_entities ) Mem_Free( svs.client_entities );
|
||||
memset( &svs, 0, sizeof(svs));
|
||||
memset( &svs, 0, sizeof( svs ));
|
||||
}
|
||||
|
||||
|
|
|
@ -982,7 +982,7 @@ void SV_CheckStuck( edict_t *ent )
|
|||
{
|
||||
if(!SV_TestEntityPosition( ent, unstickoffsets + i))
|
||||
{
|
||||
MsgDev( D_NOTE, "Unstuck player with offset %g %g %g.\n", unstickoffsets[i+0], unstickoffsets[i+1], unstickoffsets[i+2]);
|
||||
MsgDev( D_INFO, "Unstuck player with offset %g %g %g.\n", unstickoffsets[i+0], unstickoffsets[i+1], unstickoffsets[i+2]);
|
||||
SV_LinkEdict( ent );
|
||||
return;
|
||||
}
|
||||
|
@ -991,11 +991,11 @@ void SV_CheckStuck( edict_t *ent )
|
|||
VectorSubtract( ent->progs.sv->old_origin, ent->progs.sv->origin, offset );
|
||||
if(!SV_TestEntityPosition( ent, offset ))
|
||||
{
|
||||
MsgDev( D_NOTE, "Unstuck player by restoring oldorigin.\n" );
|
||||
MsgDev( D_INFO, "Unstuck player by restoring oldorigin.\n" );
|
||||
SV_LinkEdict( ent );
|
||||
return;
|
||||
}
|
||||
MsgDev( D_NOTE, "Stuck player\n" );
|
||||
MsgDev( D_INFO, "Stuck player\n" );
|
||||
}
|
||||
|
||||
bool SV_UnstickEntity( edict_t *ent )
|
||||
|
|
|
@ -159,7 +159,7 @@ void SV_SetModel (edict_t *ent, const char *name)
|
|||
vec3_t angles;
|
||||
|
||||
i = SV_ModelIndex( name );
|
||||
if(i == 0) return;
|
||||
if( i == 0 ) return;
|
||||
ent->progs.sv->model = PRVM_SetEngineString( sv.configstrings[CS_MODELS+i] );
|
||||
ent->progs.sv->modelindex = i;
|
||||
|
||||
|
@ -204,7 +204,7 @@ float SV_AngleMod( float ideal, float current, float speed )
|
|||
return anglemod(current + move);
|
||||
}
|
||||
|
||||
void SV_ConfigString (int index, const char *val)
|
||||
void SV_ConfigString( int index, const char *val )
|
||||
{
|
||||
if(index < 0 || index >= MAX_CONFIGSTRINGS)
|
||||
Host_Error ("configstring: bad index %i value %s\n", index, val);
|
||||
|
@ -591,7 +591,7 @@ void SV_ReadSaveFile( char *name )
|
|||
SV_ReadLevelFile
|
||||
=============
|
||||
*/
|
||||
void SV_ReadLevelFile( char *name )
|
||||
void SV_ReadLevelFile( const char *name )
|
||||
{
|
||||
char path[MAX_SYSPATH];
|
||||
dsavehdr_t *header;
|
||||
|
@ -760,6 +760,9 @@ bool SV_LoadEdict( edict_t *ent )
|
|||
return false;
|
||||
else if(current_skill >= 2 && (int)ent->progs.sv->spawnflags & SPAWNFLAG_NOT_HARD )
|
||||
return false;
|
||||
|
||||
// apply edict classname
|
||||
ent->priv.sv->s.classname = SV_ClassIndex(PRVM_GetString( ent->progs.sv->classname ));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -849,7 +852,7 @@ void PF_setmodel( void )
|
|||
|
||||
/*
|
||||
=================
|
||||
PF_setmodel
|
||||
PF_model_index
|
||||
|
||||
float model_index( string s )
|
||||
=================
|
||||
|
@ -1336,22 +1339,56 @@ void PF_droptofloor( void )
|
|||
|
||||
VectorCopy( ent->progs.sv->origin, end );
|
||||
end[2] -= 256;
|
||||
trace = SV_Trace(ent->progs.sv->origin, ent->progs.sv->mins, ent->progs.sv->maxs, end, MOVE_NORMAL, ent, MASK_SOLID );
|
||||
SV_UnstickEntity( ent );
|
||||
|
||||
trace = SV_Trace(ent->progs.sv->origin, ent->progs.sv->mins, ent->progs.sv->maxs, end, MOVE_NORMAL, ent, SV_ContentsMask( ent ));
|
||||
|
||||
if( trace.startsolid )
|
||||
{
|
||||
VM_Warning("droptofloor: %s startsolid at %g %g %g\n",
|
||||
vec3_t offset, org;
|
||||
VectorSet( offset, 0.5f * (ent->progs.sv->mins[0] + ent->progs.sv->maxs[0]), 0.5f * (ent->progs.sv->mins[1] + ent->progs.sv->maxs[1]), ent->progs.sv->mins[2]);
|
||||
VectorAdd( ent->progs.sv->origin, offset, org );
|
||||
trace = SV_Trace( org, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent, SV_ContentsMask( ent ));
|
||||
VectorSubtract( trace.endpos, offset, trace.endpos );
|
||||
if( trace.startsolid )
|
||||
{
|
||||
VM_Warning( "droptofloor: startsolid at %g %g %g\n", ent->progs.sv->origin[0], ent->progs.sv->origin[1], ent->progs.sv->origin[2]);
|
||||
SV_UnstickEntity( ent );
|
||||
SV_LinkEdict( ent );
|
||||
ent->progs.sv->aiflags = (int)ent->progs.sv->aiflags | AI_ONGROUND;
|
||||
ent->progs.sv->groundentity = 0;
|
||||
PRVM_G_FLOAT(OFS_RETURN) = 1;
|
||||
}
|
||||
else if( trace.fraction < 1 )
|
||||
{
|
||||
VM_Warning( "droptofloor moved to %g %g %g\n", ent->progs.sv->origin[0], ent->progs.sv->origin[1], ent->progs.sv->origin[2]);
|
||||
VectorCopy( trace.endpos, ent->progs.sv->origin );
|
||||
SV_UnstickEntity( ent );
|
||||
SV_LinkEdict( ent );
|
||||
ent->progs.sv->aiflags = (int)ent->progs.sv->aiflags | AI_ONGROUND;
|
||||
ent->progs.sv->groundentity = PRVM_EDICT_TO_PROG( trace.ent );
|
||||
PRVM_G_FLOAT(OFS_RETURN) = 1;
|
||||
// if support is destroyed, keep suspended (gross hack for floating items in various maps)
|
||||
ent->priv.sv->suspended = true;
|
||||
}
|
||||
|
||||
VM_Warning( "droptofloor: %s startsolid at %g %g %g\n",
|
||||
PRVM_G_STRING(ent->progs.sv->classname), ent->progs.sv->origin[0], ent->progs.sv->origin[1], ent->progs.sv->origin[2]);
|
||||
SV_FreeEdict (ent);
|
||||
SV_FreeEdict( ent );
|
||||
return;
|
||||
}
|
||||
if( trace.fraction != 1 )
|
||||
else
|
||||
{
|
||||
VectorCopy (trace.endpos, ent->progs.sv->origin);
|
||||
SV_LinkEdict(ent);
|
||||
ent->progs.sv->aiflags = (int)ent->progs.sv->aiflags | AI_ONGROUND;
|
||||
ent->progs.sv->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
|
||||
PRVM_G_FLOAT(OFS_RETURN) = 1;
|
||||
if( trace.fraction != 1 )
|
||||
{
|
||||
if( trace.fraction < 1 ) VectorCopy( trace.endpos, ent->progs.sv->origin );
|
||||
SV_LinkEdict( ent );
|
||||
ent->progs.sv->aiflags = (int)ent->progs.sv->aiflags | AI_ONGROUND;
|
||||
ent->progs.sv->groundentity = PRVM_EDICT_TO_PROG( trace.ent );
|
||||
PRVM_G_FLOAT(OFS_RETURN) = 1;
|
||||
// if support is destroyed, keep suspended (gross hack for floating items in various maps)
|
||||
ent->priv.sv->suspended = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1359,7 +1396,7 @@ void PF_droptofloor( void )
|
|||
===============
|
||||
PF_walkmove
|
||||
|
||||
float walkmove( float yaw, float dist )
|
||||
float walkmove( float yaw, float dist, float settrace )
|
||||
===============
|
||||
*/
|
||||
void PF_walkmove( void )
|
||||
|
@ -1369,8 +1406,9 @@ void PF_walkmove( void )
|
|||
vec3_t move;
|
||||
mfunction_t *oldf;
|
||||
int oldpev;
|
||||
bool settrace;
|
||||
|
||||
if(!VM_ValidateArgs( "walkmove", 0 )) return;
|
||||
if(!VM_ValidateArgs( "walkmove", 3 )) return;
|
||||
PRVM_G_FLOAT(OFS_RETURN) = 0; // assume failure if it returns early
|
||||
ent = PRVM_PROG_TO_EDICT( prog->globals.sv->pev );
|
||||
|
||||
|
@ -1387,19 +1425,19 @@ void PF_walkmove( void )
|
|||
|
||||
yaw = PRVM_G_FLOAT(OFS_PARM0);
|
||||
dist = PRVM_G_FLOAT(OFS_PARM1);
|
||||
settrace = (int)PRVM_G_FLOAT(OFS_PARM2);
|
||||
|
||||
if(!((int)ent->progs.sv->aiflags & (AI_ONGROUND|AI_FLY|AI_SWIM)))
|
||||
return;
|
||||
|
||||
yaw = yaw * M_PI*2 / 360;
|
||||
|
||||
VectorSet( move, cos(yaw) * dist, sin(yaw) * dist, 0 );
|
||||
VectorSet( move, (cos(yaw) * dist), (sin(yaw) * dist), 0.0f );
|
||||
|
||||
// save program state, because SV_MoveStep may call other progs
|
||||
oldf = prog->xfunction;
|
||||
oldpev = prog->globals.sv->pev;
|
||||
|
||||
PRVM_G_FLOAT(OFS_RETURN) = SV_movestep( ent, move, true, false, true );
|
||||
PRVM_G_FLOAT(OFS_RETURN) = SV_movestep( ent, move, true, false, settrace );
|
||||
|
||||
// restore program state
|
||||
prog->xfunction = oldf;
|
||||
|
@ -1541,14 +1579,14 @@ void PF_ambientsound( void )
|
|||
=================
|
||||
PF_traceline
|
||||
|
||||
void traceline( vector v1, vector v2, float mask, entity ignore )
|
||||
void traceline( vector v1, vector v2, float move, entity ignore )
|
||||
=================
|
||||
*/
|
||||
void PF_traceline( void )
|
||||
{
|
||||
float *v1, *v2;
|
||||
trace_t trace;
|
||||
int mask;
|
||||
int move;
|
||||
edict_t *ent;
|
||||
|
||||
if(!VM_ValidateArgs( "traceline", 4 )) return;
|
||||
|
@ -1556,31 +1594,16 @@ void PF_traceline( void )
|
|||
|
||||
v1 = PRVM_G_VECTOR(OFS_PARM0);
|
||||
v2 = PRVM_G_VECTOR(OFS_PARM1);
|
||||
mask = (int)PRVM_G_FLOAT(OFS_PARM2);
|
||||
move = (int)PRVM_G_FLOAT(OFS_PARM2);
|
||||
ent = PRVM_G_EDICT(OFS_PARM3);
|
||||
|
||||
if(mask == 1) mask = MASK_SOLID;
|
||||
else if(mask == 2) mask = MASK_SHOT;
|
||||
else if(mask == 3) mask = MASK_MONSTERSOLID;
|
||||
else if(mask == 4) mask = MASK_WATER;
|
||||
else mask = MASK_ALL;
|
||||
|
||||
if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
|
||||
PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n",
|
||||
PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], mask, PRVM_EDICT_TO_PROG(ent));
|
||||
PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
|
||||
|
||||
trace = SV_Trace( v1, vec3_origin, vec3_origin, v2, MOVE_NORMAL, ent, mask );
|
||||
trace = SV_Trace( v1, vec3_origin, vec3_origin, v2, move, ent, SV_ContentsMask(ent));
|
||||
|
||||
prog->globals.sv->trace_allsolid = trace.allsolid;
|
||||
prog->globals.sv->trace_startsolid = trace.startsolid;
|
||||
prog->globals.sv->trace_fraction = trace.fraction;
|
||||
prog->globals.sv->trace_contents = trace.contents;
|
||||
|
||||
VectorCopy (trace.endpos, prog->globals.sv->trace_endpos);
|
||||
VectorCopy (trace.plane.normal, prog->globals.sv->trace_plane_normal);
|
||||
prog->globals.sv->trace_plane_dist = trace.plane.dist;
|
||||
if (trace.ent) prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
|
||||
else prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
|
||||
VM_SetTraceGlobals( &trace );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1625,14 +1648,14 @@ void PF_tracetoss( void )
|
|||
=================
|
||||
PF_tracebox
|
||||
|
||||
void tracebox( vector v1, vector mins, vector maxs, vector v2, float mask, entity ignore )
|
||||
void tracebox( vector v1, vector mins, vector maxs, vector v2, float move, entity ignore )
|
||||
=================
|
||||
*/
|
||||
void PF_tracebox( void )
|
||||
{
|
||||
float *v1, *v2, *m1, *m2;
|
||||
trace_t trace;
|
||||
int mask;
|
||||
int move;
|
||||
edict_t *ent;
|
||||
|
||||
if(!VM_ValidateArgs( "tracebox", 6 )) return;
|
||||
|
@ -1642,33 +1665,16 @@ void PF_tracebox( void )
|
|||
m1 = PRVM_G_VECTOR(OFS_PARM1);
|
||||
m2 = PRVM_G_VECTOR(OFS_PARM2);
|
||||
v2 = PRVM_G_VECTOR(OFS_PARM3);
|
||||
mask = (int)PRVM_G_FLOAT(OFS_PARM4);
|
||||
move = (int)PRVM_G_FLOAT(OFS_PARM4);
|
||||
ent = PRVM_G_EDICT(OFS_PARM5);
|
||||
|
||||
if( mask == 1 ) mask = MASK_SOLID;
|
||||
else if( mask == 2 ) mask = MASK_SHOT;
|
||||
else if( mask == 3 ) mask = MASK_MONSTERSOLID;
|
||||
else if( mask == 4 ) mask = MASK_PLAYERSOLID;
|
||||
else if( mask == 5 ) mask = MASK_WATER;
|
||||
else mask = MASK_ALL;
|
||||
|
||||
if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2]))
|
||||
PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n",
|
||||
PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], mask, PRVM_EDICT_TO_PROG(ent));
|
||||
PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
|
||||
|
||||
trace = SV_Trace( v1, m1, m2, v2, MOVE_NORMAL, ent, mask );
|
||||
trace = SV_Trace( v1, m1, m2, v2, move, ent, SV_ContentsMask( ent ));
|
||||
|
||||
prog->globals.sv->trace_allsolid = trace.allsolid;
|
||||
prog->globals.sv->trace_startsolid = trace.startsolid;
|
||||
prog->globals.sv->trace_fraction = trace.fraction;
|
||||
prog->globals.sv->trace_contents = trace.contents;
|
||||
|
||||
VectorCopy( trace.endpos, prog->globals.sv->trace_endpos );
|
||||
VectorCopy( trace.plane.normal, prog->globals.sv->trace_plane_normal );
|
||||
prog->globals.sv->trace_plane_dist = trace.plane.dist;
|
||||
|
||||
if( trace.ent ) prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG( trace.ent );
|
||||
else prog->globals.sv->trace_ent = PRVM_EDICT_TO_PROG( prog->edicts );
|
||||
VM_SetTraceGlobals( &trace );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1836,7 +1842,7 @@ void PF_particle( void )
|
|||
color = PRVM_G_FLOAT(OFS_PARM2);
|
||||
count = PRVM_G_FLOAT(OFS_PARM3);
|
||||
|
||||
SV_StartParticle (org, dir, (int)color, (int)count);
|
||||
SV_StartParticle( org, dir, (int)color, (int)count);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1859,23 +1865,7 @@ void PF_lightstyle( void )
|
|||
|
||||
if((uint)style >= MAX_LIGHTSTYLES )
|
||||
PRVM_ERROR( "PF_lightstyle: style: %i >= %d", style, MAX_LIGHTSTYLES );
|
||||
SV_ConfigString( CS_LIGHTS + style, val );
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
PF_decalindex
|
||||
|
||||
float decal_index( string s )
|
||||
===============
|
||||
*/
|
||||
void PF_decalindex( void )
|
||||
{
|
||||
if(!VM_ValidateArgs( "decal_index", 1 ))
|
||||
return;
|
||||
|
||||
VM_ValidateString(PRVM_G_STRING(OFS_PARM0));
|
||||
PRVM_G_FLOAT(OFS_RETURN) = SV_DecalIndex(PRVM_G_STRING(OFS_PARM0)); // it will precache new decals too
|
||||
SV_ConfigString( CS_LIGHTSTYLES + style, val );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2143,18 +2133,23 @@ void PF_InfoSetValueForKey( void )
|
|||
|
||||
/*
|
||||
===============
|
||||
PF_Configstring
|
||||
PF_setsky
|
||||
|
||||
void configstring( float num, string s )
|
||||
void setsky( string name, vector angles, float speed )
|
||||
===============
|
||||
*/
|
||||
void PF_configstring( void )
|
||||
void PF_setsky( void )
|
||||
{
|
||||
if(!VM_ValidateArgs( "configstring", 2 ))
|
||||
float *ang;
|
||||
|
||||
if(!VM_ValidateArgs( "setsky", 3 ))
|
||||
return;
|
||||
|
||||
VM_ValidateString(PRVM_G_STRING(OFS_PARM1));
|
||||
SV_ConfigString((int)PRVM_G_FLOAT(OFS_PARM0), PRVM_G_STRING(OFS_PARM1));
|
||||
VM_ValidateString(PRVM_G_STRING(OFS_PARM0));
|
||||
ang = PRVM_G_VECTOR(OFS_PARM1);
|
||||
SV_ConfigString( CS_SKYNAME, PRVM_G_STRING(OFS_PARM0));
|
||||
SV_ConfigString( CS_SKYANGLES, va( "%g %g %g", ang[0], ang[1], ang[2] ));
|
||||
SV_ConfigString( CS_SKYSPEED, va("%g", PRVM_G_FLOAT(OFS_PARM2)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2324,7 +2319,7 @@ PF_serverexec, // #141 void server_execute( void )
|
|||
PF_clientcmd, // #142 void client_command( entity e, string s)
|
||||
PF_particle, // #143 void particle( vector origin, vector dir, float color, float count )
|
||||
PF_lightstyle, // #144 void lightstyle(float style, string value)
|
||||
PF_decalindex, // #145 float decal_index(string s)
|
||||
NULL, // #145
|
||||
PF_pointcontents, // #146 float pointcontents(vector v)
|
||||
PF_BeginMessage, // #147 void MsgBegin (float dest)
|
||||
PF_EndMessage, // #148 void MsgEnd(float to, vector pos, entity e)
|
||||
|
@ -2352,7 +2347,7 @@ PF_InfoPrint, // #169 void Info_Print( entity client )
|
|||
PF_InfoValueForKey, // #170 string Info_ValueForKey( entity client, string key )
|
||||
PF_InfoRemoveKey, // #171 void Info_RemoveKey( entity client, string key )
|
||||
PF_InfoSetValueForKey, // #172 void Info_SetValueForKey( entity client, string key, string value )
|
||||
PF_configstring, // #173 void configstring(float num, string s)
|
||||
PF_setsky, // #173 void setsky( string name, vector angles, float speed )
|
||||
NULL, // #174 staticDecal
|
||||
};
|
||||
|
||||
|
|
|
@ -1666,9 +1666,9 @@ static file_t* FS_SysOpen (const char* filepath, const char* mode )
|
|||
Msg("FS_SysOpen(%s, %s): invalid mode\n", filepath, mode);
|
||||
return NULL;
|
||||
}
|
||||
for (ind = 1; mode[ind] != '\0'; ind++)
|
||||
for( ind = 1; mode[ind] != '\0'; ind++ )
|
||||
{
|
||||
switch (mode[ind])
|
||||
switch( mode[ind] )
|
||||
{
|
||||
case '+':
|
||||
mod = O_RDWR;
|
||||
|
@ -1677,7 +1677,8 @@ static file_t* FS_SysOpen (const char* filepath, const char* mode )
|
|||
opt |= O_BINARY;
|
||||
break;
|
||||
default:
|
||||
Msg("FS_SysOpen(%s, %s): unknown character in mode (%c)\n", filepath, mode, mode[ind]);
|
||||
MsgDev( D_ERROR, "FS_SysOpen: %s: unknown char in mode (%c)\n", filepath, mode, mode[ind] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -245,7 +245,6 @@ physbody_t *Phys_CreatePlayer( sv_edict_t *ed, cmodel_t *mod, matrix4x3 transfor
|
|||
matrix4x4 trans;
|
||||
vec3_t radius, mins, maxs, upDirection;
|
||||
|
||||
Msg("Phys_CreatePlayer: %d\n", cm_physics_model->integer );
|
||||
if( !cm_physics_model->integer )
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -1036,8 +1036,26 @@ _inline float RadiusFromBounds( vec3_t mins, vec3_t maxs )
|
|||
return VectorLength( corner );
|
||||
}
|
||||
|
||||
_inline float LerpAngle( float a2, float a1, float frac )
|
||||
{
|
||||
if( a1 - a2 > 180 ) a1 -= 360;
|
||||
if( a1 - a2 < -180 ) a1 += 360;
|
||||
return a2 + frac * (a1 - a2);
|
||||
}
|
||||
|
||||
_inline float LerpView( float org1, float org2, float ofs1, float ofs2, float frac )
|
||||
{
|
||||
return org1 + ofs1 + frac * (org2 + ofs2 - (org1 + ofs1));
|
||||
}
|
||||
|
||||
_inline float LerpPoint( float oldpoint, float curpoint, float frac )
|
||||
{
|
||||
return oldpoint + frac * (curpoint - oldpoint);
|
||||
}
|
||||
|
||||
static vec3_t vec3_origin = { 0, 0, 0 };
|
||||
static vec3_t vec3_angles = { 0, 0, 0 };
|
||||
static vec4_t vec4_origin = { 0, 0, 0, 0 };
|
||||
static vec3_t vec3_up = { 0.0f, 1.0f, 0.0f }; // unconverted up vector
|
||||
|
||||
#endif//BASEMATH_H
|
|
@ -129,8 +129,7 @@ BRUSH MODELS
|
|||
#define MAX_MAP_STRINGDATA 0x40000
|
||||
#define MAX_MAP_NUMSTRINGS 0x10000
|
||||
|
||||
// game limits
|
||||
#define MAX_MODELS MAX_MAP_MODELS>>1 // brushmodels and other models
|
||||
// world limits
|
||||
#define MAX_WORLD_COORD ( 128 * 1024 )
|
||||
#define MIN_WORLD_COORD (-128 * 1024 )
|
||||
#define WORLD_SIZE ( MAX_WORLD_COORD - MIN_WORLD_COORD )
|
||||
|
@ -507,8 +506,8 @@ Studio models are position independent, so the cache manager can move them.
|
|||
#define MAXSTUDIOEVENTS 1024 // events per model
|
||||
#define MAXSTUDIOPIVOTS 256 // pivot points
|
||||
#define MAXSTUDIOBLENDS 8 // max anim blends
|
||||
#define MAXSTUDIOCONTROLLERS 32 // max controllers per model
|
||||
#define MAXSTUDIOATTACHMENTS 32 // max attachments per model
|
||||
#define MAXSTUDIOCONTROLLERS 16 // max controllers per model
|
||||
#define MAXSTUDIOATTACHMENTS 16 // max attachments per model
|
||||
|
||||
// model global flags
|
||||
#define STUDIO_STATIC 0x0001 // model without anims
|
||||
|
|
|
@ -26,7 +26,7 @@ enum host_state
|
|||
COMP_STUDIO, // "studio"
|
||||
COMP_WADLIB, // "wadlib"
|
||||
RIPP_MIPDEC, // "mipdec"
|
||||
RIPP_SPRDEC, // "sprdec"
|
||||
RIPP_SPRDEC, // "sprdec"
|
||||
RIPP_MDLDEC, // "mdldec"
|
||||
RIPP_LMPDEC, // "lmpdec"
|
||||
RIPP_SNDDEC, // "snddec"
|
||||
|
@ -92,7 +92,6 @@ typedef struct file_s file_t;
|
|||
typedef struct vfile_s vfile_t;
|
||||
typedef struct image_s image_t;
|
||||
typedef struct model_s model_t;
|
||||
|
||||
typedef void (*xcommand_t) (void);
|
||||
|
||||
typedef enum
|
||||
|
@ -162,7 +161,7 @@ typedef struct model_state_s
|
|||
int skin; // skin for studiomodels
|
||||
int body; // sub-model selection for studiomodels
|
||||
float blending[8]; // studio animation blending
|
||||
float controller[32]; // studio bone controllers
|
||||
float controller[16]; // studio bone controllers
|
||||
} model_state_t;
|
||||
|
||||
// entity_state_t communication
|
||||
|
@ -171,6 +170,7 @@ typedef struct entity_state_s
|
|||
// engine specific
|
||||
uint number; // edict index
|
||||
edtype_t ed_type; // edict type
|
||||
string_t classname; // edict classname
|
||||
int soundindex; // looped ambient sound
|
||||
|
||||
// physics information
|
||||
|
@ -206,7 +206,6 @@ typedef struct entity_state_s
|
|||
int maxspeed; // sv_maxspeed will be duplicate on all clients
|
||||
float health; // client health (other parms can be send by custom messages)
|
||||
float fov; // horizontal field of view
|
||||
model_state_t vmodel; // viewmodel info
|
||||
model_state_t pmodel; // weaponmodel info
|
||||
} entity_state_t;
|
||||
|
||||
|
@ -877,28 +876,37 @@ typedef struct cvar_s
|
|||
#endif
|
||||
|
||||
// euler angle order
|
||||
#define PITCH 0
|
||||
#define YAW 1
|
||||
#define ROLL 2
|
||||
#define PITCH 0
|
||||
#define YAW 1
|
||||
#define ROLL 2
|
||||
|
||||
#define MAX_LIGHTSTYLES 256
|
||||
#define MAX_EDICTS 65535 // absolute limit that never be reached
|
||||
//
|
||||
// engine constnat limits, touching networking protocol modify with cation
|
||||
//
|
||||
#define MAX_DLIGHTS 128 // dynamic lights (per one frame)
|
||||
#define MAX_LIGHTSTYLES 256 // can be blindly increased
|
||||
#define MAX_CLASSNAMES 512 // maxcount of various edicts classnames
|
||||
#define MAX_SOUNDS 512 // openal software limit
|
||||
#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 EF_ROTATE (1<<0) // rotate (bonus items)
|
||||
// entity_state_t->effects
|
||||
#define EF_ROTATE (1<<0) // rotate (bonus items)
|
||||
|
||||
// shared client/renderer flags
|
||||
#define RF_MINLIGHT 1 // allways have some light (viewmodel)
|
||||
#define RF_PLAYERMODEL 2 // don't draw through eyes, only mirrors
|
||||
#define RF_VIEWMODEL 4 // it's a viewmodel
|
||||
#define RF_FULLBRIGHT 8 // allways draw full intensity
|
||||
#define RF_DEPTHHACK 16 // for view weapon Z crunching
|
||||
#define RF_TRANSLUCENT 32
|
||||
#define RF_IR_VISIBLE 64 // skin is an index in image_precache
|
||||
// entity_state_t->renderfx
|
||||
#define RF_MINLIGHT (1<<0) // allways have some light (viewmodel)
|
||||
#define RF_PLAYERMODEL (1<<1) // don't draw through eyes, only mirrors
|
||||
#define RF_VIEWMODEL (1<<2) // it's a viewmodel
|
||||
#define RF_FULLBRIGHT (1<<3) // allways draw full intensity
|
||||
#define RF_DEPTHHACK (1<<4) // for view weapon Z crunching
|
||||
#define RF_TRANSLUCENT (1<<5)
|
||||
#define RF_IR_VISIBLE (1<<6) // skin is an index in image_precache
|
||||
|
||||
// render private flags
|
||||
#define RDF_NOWORLDMODEL 1 // used for player configuration screen
|
||||
#define RDF_IRGOGGLES 2
|
||||
#define RDF_PAIN 4
|
||||
// FIXME: player_state_t->renderfx
|
||||
#define RDF_NOWORLDMODEL (1<<0) // used for player configuration screen
|
||||
#define RDF_IRGOGGLES (1<<1)
|
||||
#define RDF_PAIN (1<<2)
|
||||
|
||||
// encoded bmodel mask
|
||||
#define SOLID_BMODEL 0xffffff
|
||||
|
@ -1123,133 +1131,35 @@ typedef struct trace_s
|
|||
#define ATTN_IDLE 2
|
||||
#define ATTN_STATIC 3 // Diminish very rapidly with distance
|
||||
|
||||
// player_state->stats[] indexes
|
||||
enum player_stats
|
||||
typedef struct vrect_s
|
||||
{
|
||||
STAT_HEALTH_ICON = 0,
|
||||
STAT_HEALTH,
|
||||
STAT_AMMO_ICON,
|
||||
STAT_AMMO,
|
||||
STAT_ARMOR_ICON,
|
||||
STAT_ARMOR,
|
||||
STAT_SELECTED_ICON,
|
||||
STAT_PICKUP_ICON,
|
||||
STAT_PICKUP_STRING,
|
||||
STAT_TIMER_ICON,
|
||||
STAT_TIMER,
|
||||
STAT_HELPICON,
|
||||
STAT_SELECTED_ITEM,
|
||||
STAT_LAYOUTS,
|
||||
STAT_FRAGS,
|
||||
STAT_FLASHES, // cleared each frame, 1 = health, 2 = armor
|
||||
STAT_CHASE,
|
||||
STAT_SPECTATOR,
|
||||
STAT_SPEED = 22,
|
||||
STAT_ZOOM,
|
||||
MAX_STATS = 32,
|
||||
};
|
||||
|
||||
typedef struct dlight_s
|
||||
{
|
||||
vec3_t origin;
|
||||
vec3_t color;
|
||||
float intensity;
|
||||
|
||||
} dlight_t;
|
||||
|
||||
typedef struct particle_s
|
||||
{
|
||||
vec3_t origin;
|
||||
int color;
|
||||
float alpha;
|
||||
|
||||
} particle_t;
|
||||
|
||||
typedef struct lightstyle_s
|
||||
{
|
||||
float rgb[3]; // 0.0 - 2.0
|
||||
float white; // highest of rgb
|
||||
|
||||
} lightstyle_t;
|
||||
|
||||
typedef struct latchedvars_s
|
||||
{
|
||||
float animtime;
|
||||
float sequencetime;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
|
||||
int sequence;
|
||||
float frame;
|
||||
|
||||
byte blending[MAXSTUDIOBLENDS];
|
||||
byte seqblending[MAXSTUDIOBLENDS];
|
||||
byte controller[MAXSTUDIOCONTROLLERS];
|
||||
|
||||
} latchedvars_t;
|
||||
|
||||
// client entity
|
||||
typedef struct entity_s
|
||||
{
|
||||
model_t *model; // opaque type outside refresh
|
||||
model_t *weaponmodel; // opaque type outside refresh
|
||||
|
||||
latchedvars_t prev; // previous frame values for lerping
|
||||
|
||||
vec3_t angles;
|
||||
vec3_t origin; // also used as RF_BEAM's "from"
|
||||
float oldorigin[3]; // also used as RF_BEAM's "to"
|
||||
|
||||
float animtime;
|
||||
float frame; // also used as RF_BEAM's diameter
|
||||
float framerate;
|
||||
|
||||
int body;
|
||||
int skin;
|
||||
|
||||
byte blending[MAXSTUDIOBLENDS];
|
||||
byte controller[MAXSTUDIOCONTROLLERS];
|
||||
byte mouth; //TODO: move to struct
|
||||
|
||||
int movetype; //entity moving type
|
||||
int sequence;
|
||||
float scale;
|
||||
|
||||
vec3_t attachment[MAXSTUDIOATTACHMENTS];
|
||||
|
||||
// misc
|
||||
float backlerp; // 0.0 = current, 1.0 = old
|
||||
int skinnum; // also used as RF_BEAM's palette index
|
||||
|
||||
int lightstyle; // for flashing entities
|
||||
float alpha; // ignore if RF_TRANSLUCENT isn't set
|
||||
int flags;
|
||||
|
||||
} entity_t;
|
||||
int x, y;
|
||||
int width;
|
||||
int height;
|
||||
} vrect_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x, y, width, height;// in virtual screen coordinates
|
||||
float fov_x, fov_y;
|
||||
float vieworg[3];
|
||||
float viewangles[3];
|
||||
float blend[4]; // rgba 0-1 full screen blend
|
||||
vrect_t rect;
|
||||
float fov_x;
|
||||
float fov_y;
|
||||
vec3_t vieworg;
|
||||
vec3_t viewangles;
|
||||
vec4_t blend; // rgba 0-1 full screen blend
|
||||
float time; // time is used to auto animate
|
||||
int rdflags; // RDF_UNDERWATER, etc
|
||||
uint rdflags; // RDF_UNDERWATER, etc
|
||||
byte *mempool; // entities, dlights etc
|
||||
|
||||
// chains are stored in dynamically resized arrays
|
||||
byte *areabits; // if not NULL, only areas with set bits will be drawn
|
||||
struct lightstyle_s *lightstyles; // [MAX_LIGHTSTYLES]
|
||||
struct particle_s *particles;
|
||||
struct ref_entity_s *entities; // [MAX_EDICTS]
|
||||
struct dlight_s *dlights;
|
||||
|
||||
lightstyle_t *lightstyles; // [MAX_LIGHTSTYLES]
|
||||
|
||||
int num_particles;
|
||||
int num_entities;
|
||||
entity_t *entities; // [MAX_EDICTS]
|
||||
|
||||
int num_dlights;
|
||||
dlight_t *dlights;
|
||||
|
||||
int num_particles;
|
||||
particle_t *particles;
|
||||
|
||||
} refdef_t;
|
||||
|
||||
typedef struct pmove_s
|
||||
|
@ -1345,21 +1255,28 @@ RENDER.DLL INTERFACE
|
|||
typedef struct render_exp_s
|
||||
{
|
||||
// interface validator
|
||||
size_t api_size; // must matched with sizeof(render_exp_t)
|
||||
size_t api_size; // must matched with sizeof(render_exp_t)
|
||||
|
||||
// initialize
|
||||
bool (*Init)( void *hInst ); // init all render systems
|
||||
void (*Shutdown)( void ); // shutdown all render systems
|
||||
bool (*Init)( void *hInst ); // init all render systems
|
||||
void (*Shutdown)( void ); // shutdown all render systems
|
||||
|
||||
void (*BeginRegistration) (char *map);
|
||||
model_t *(*RegisterModel) (char *name);
|
||||
image_t *(*RegisterSkin) (char *name);
|
||||
bool (*RegisterModel)( const char *name, int sv_index );
|
||||
bool (*RegisterImage)( const char *name, int sv_index );
|
||||
image_t *(*RegisterPic) (char *name);
|
||||
void (*SetSky) (char *name, float rotate, vec3_t axis);
|
||||
void (*EndRegistration) (void);
|
||||
void (*EndRegistration)( void );
|
||||
|
||||
// prepare frame to rendering
|
||||
bool (*AddRefEntity)( refdef_t *fd, entity_state_t *s1, entity_state_t *s2, float lerp );
|
||||
bool (*AddDynLight)( refdef_t *fd, vec3_t org, vec3_t color, float intensity );
|
||||
bool (*AddParticle)( refdef_t *fd, vec3_t org, float alpha, int color );
|
||||
bool (*AddLightStyle)( refdef_t *fd, int stylenum, vec3_t color );
|
||||
void (*ClearScene)( refdef_t *fd );
|
||||
|
||||
void (*BeginFrame)( void );
|
||||
void (*RenderFrame) (refdef_t *fd);
|
||||
void (*RenderFrame)( refdef_t *fd );
|
||||
void (*EndFrame)( void );
|
||||
|
||||
void (*SetColor)( const float *rgba );
|
||||
|
@ -1378,7 +1295,7 @@ typedef struct render_imp_s
|
|||
size_t api_size; // must matched with sizeof(render_imp_t)
|
||||
|
||||
// client fundamental callbacks
|
||||
void (*StudioEvent)( mstudioevent_t *event, entity_t *ent );
|
||||
void (*StudioEvent)( mstudioevent_t *event, entity_state_t *ent );
|
||||
void (*ShowCollision)( cmdraw_t callback ); // debug
|
||||
long (*WndProc)( void *hWnd, uint uMsg, uint wParam, long lParam );
|
||||
} render_imp_t;
|
||||
|
|
|
@ -454,7 +454,6 @@ void GL_InitBackend( void )
|
|||
void GL_ShutdownBackend( void )
|
||||
{
|
||||
if( r_framebuffer ) Z_Free( r_framebuffer );
|
||||
|
||||
GL_RemoveCommands();
|
||||
}
|
||||
|
||||
|
|
|
@ -291,8 +291,8 @@ void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data
|
|||
Host_Error( "Draw_StretchRaw: size not a power of 2: %i by %i\n", cols, rows );
|
||||
GL_Bind( 0 );
|
||||
if( dirty ) pglTexImage2D (GL_TEXTURE_2D, 0, gl_tex_solid_format, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||
pglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
|
||||
pglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
|
||||
pglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max );
|
||||
pglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max );
|
||||
R_SetGL2D();
|
||||
|
||||
pglColor4fv(gl_state.draw_color);
|
||||
|
|
|
@ -269,10 +269,9 @@ int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
|
|||
|
||||
lightmap += 3*(dt * ((surf->extents[0]>>4)+1) + ds);
|
||||
|
||||
for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
|
||||
maps++)
|
||||
for( maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255; maps++ )
|
||||
{
|
||||
for (i=0 ; i<3 ; i++)
|
||||
for( i = 0; i < 3; i++ )
|
||||
scale[i] = gl_modulate->value*r_newrefdef.lightstyles[surf->styles[maps]].rgb[i];
|
||||
|
||||
pointcolor[0] += lightmap[0] * scale[0] * (1.0/255);
|
||||
|
@ -303,10 +302,11 @@ void R_LightPoint (vec3_t p, vec3_t color)
|
|||
float light;
|
||||
vec3_t dist;
|
||||
float add;
|
||||
|
||||
if (!r_worldmodel->lightdata)
|
||||
|
||||
// viewport can't have lightdata
|
||||
if( r_newrefdef.rdflags && RDF_NOWORLDMODEL || !r_worldmodel->lightdata )
|
||||
{
|
||||
color[0] = color[1] = color[2] = 1.0;
|
||||
color[0] = color[1] = color[2] = 1.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define WINDOW_STYLE (WS_OVERLAPPED|WS_BORDER|WS_CAPTION|WS_VISIBLE)
|
||||
|
||||
#include "r_opengl.h"
|
||||
#include "r_local.h" // temporary
|
||||
|
||||
/*
|
||||
===========================================
|
||||
|
@ -174,12 +175,12 @@ extern image_t *r_notexture;
|
|||
extern image_t *r_particletexture;
|
||||
extern image_t *r_radarmap;
|
||||
extern image_t *r_around;
|
||||
extern entity_t *currententity;
|
||||
extern model_t *currentmodel;
|
||||
extern int r_visframecount;
|
||||
extern int r_framecount;
|
||||
extern cplane_t frustum[4];
|
||||
extern int c_brush_polys;
|
||||
extern ref_entity_t *currententity;
|
||||
extern model_t *currentmodel;
|
||||
extern int r_visframecount;
|
||||
extern int r_framecount;
|
||||
extern cplane_t frustum[4];
|
||||
extern int c_brush_polys;
|
||||
|
||||
|
||||
extern int gl_filter_min, gl_filter_max;
|
||||
|
@ -293,6 +294,7 @@ extern int c_visible_textures;
|
|||
|
||||
extern float r_world_matrix[16];
|
||||
extern float r_turbsin[256];
|
||||
extern model_t *r_models[MAX_MODELS];
|
||||
|
||||
void R_TranslatePlayerSkin (int playernum);
|
||||
void GL_Bind (int texnum);
|
||||
|
@ -330,7 +332,7 @@ void R_StudioLoadModel (model_t *mod, void *buffer );
|
|||
void R_SpriteLoadModel( model_t *mod, void *buffer );
|
||||
void R_DrawPauseScreen( void );
|
||||
char *R_ExtName( model_t *mod );
|
||||
void R_DrawBeam( entity_t *e );
|
||||
void R_DrawBeam( ref_entity_t *e );
|
||||
void R_DrawWorld (void);
|
||||
void R_RenderDlights (void);
|
||||
void R_DrawAlphaSurfaces (void);
|
||||
|
@ -339,7 +341,7 @@ void R_InitParticleTexture (void);
|
|||
void Draw_InitLocal (void);
|
||||
void GL_SubdivideSurface (msurface_t *fa);
|
||||
bool R_CullBox (vec3_t mins, vec3_t maxs);
|
||||
void R_RotateForEntity (entity_t *e);
|
||||
void R_RotateForEntity( ref_entity_t *e );
|
||||
void R_MarkLeaves (void);
|
||||
|
||||
void GL_DrawRadar( refdef_t *fd );
|
||||
|
@ -367,7 +369,6 @@ void Draw_Fill(float x, float y, float w, float h );
|
|||
void Draw_FadeScreen (void);
|
||||
void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data, bool dirty );
|
||||
|
||||
void R_BeginFrame( void );
|
||||
void R_SwapBuffers( int );
|
||||
void R_SetPalette ( const unsigned char *palette);
|
||||
void R_GetPalette (void);
|
||||
|
@ -411,8 +412,6 @@ void GL_DrawParticles( int n, const particle_t particles[], const unsigned color
|
|||
#define GL_RENDERER_NVIDIA 0x00000004
|
||||
#define GL_RENDERER_DEFAULT 0x80000000
|
||||
|
||||
#include "r_local.h" // temporary
|
||||
|
||||
extern glconfig_t gl_config;
|
||||
extern glstate_t gl_state;
|
||||
|
||||
|
@ -435,6 +434,12 @@ void GL_SetExtension( int r_ext, int enable );
|
|||
void GL_PolygonOffset( float planeoffset, float depthoffset );
|
||||
void GL_CheckExtension( const char *name, const dllfunc_t *funcs, const char *cvarname, int r_ext );
|
||||
|
||||
void R_BeginRegistration( char *map );
|
||||
model_t *R_RegisterModel( const char *name );
|
||||
void R_SetSky (char *name, float rotate, vec3_t axis);
|
||||
void R_EndRegistration (void);
|
||||
image_t *Draw_FindPic( const char *name );
|
||||
|
||||
/*
|
||||
====================================================================
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ int registration_sequence;
|
|||
|
||||
const char *Mod_GetStringFromTable( int index )
|
||||
{
|
||||
if(loadmodel->stringdata)
|
||||
if( loadmodel->stringdata )
|
||||
return &loadmodel->stringdata[loadmodel->stringtable[index]];
|
||||
return NULL;
|
||||
}
|
||||
|
@ -174,19 +174,19 @@ Mod_ForName
|
|||
Loads in a model for the given name
|
||||
==================
|
||||
*/
|
||||
model_t *Mod_ForName(char *name, bool crash)
|
||||
model_t *Mod_ForName( const char *name, bool crash)
|
||||
{
|
||||
model_t *mod;
|
||||
uint *buf;
|
||||
int i;
|
||||
|
||||
if (!name[0]) return NULL;
|
||||
if( !name[0] ) return NULL;
|
||||
|
||||
// inline models are grabbed only from worldmodel
|
||||
if (name[0] == '*')
|
||||
if( name[0] == '*' )
|
||||
{
|
||||
i = atoi(name + 1);
|
||||
if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)
|
||||
i = com.atoi(name + 1);
|
||||
if( i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)
|
||||
{
|
||||
Msg("Warning: bad inline model number %i\n", i );
|
||||
return NULL;
|
||||
|
@ -197,7 +197,7 @@ model_t *Mod_ForName(char *name, bool crash)
|
|||
}
|
||||
|
||||
// search the currently loaded models
|
||||
for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++)
|
||||
for( i = 0, mod = mod_known; i < mod_numknown; i++, mod++ )
|
||||
{
|
||||
if (!mod->name[0]) continue;
|
||||
if (!com.strcmp (mod->name, name))
|
||||
|
@ -457,38 +457,27 @@ void Mod_LoadSurfDesc( lump_t *l )
|
|||
|
||||
for ( i = 0; i < count; i++, in++, out++)
|
||||
{
|
||||
char texname[128];
|
||||
|
||||
for (j = 0; j < 8; j++)
|
||||
for( j = 0; j < 8; j++ )
|
||||
out->vecs[0][j] = LittleFloat(in->vecs[0][j]);
|
||||
|
||||
out->flags = LittleLong (in->flags);
|
||||
next = LittleLong (in->animid);
|
||||
if (next > 0) out->next = loadmodel->texinfo + next;
|
||||
if( next > 0 ) out->next = loadmodel->texinfo + next;
|
||||
else out->next = NULL;
|
||||
|
||||
// fixed texture size
|
||||
out->size[0] = LittleLong (in->size[0]);
|
||||
out->size[1] = LittleLong (in->size[1]);
|
||||
|
||||
com.strncpy( texname, Mod_GetStringFromTable( LittleLong( in->texid )), sizeof(texname));
|
||||
out->image = R_FindImage( texname, NULL, 0, it_wall );
|
||||
if(out->image)
|
||||
{
|
||||
Cvar_SetValue("scr_loading", r_loading->value + 45.0f/count );
|
||||
}
|
||||
else
|
||||
{
|
||||
Msg("Couldn't load %s\n", texname );
|
||||
out->image = r_notexture;
|
||||
}
|
||||
out->size[0] = LittleLong( in->size[0] );
|
||||
out->size[1] = LittleLong( in->size[1] );
|
||||
out->texid = LittleLong( in->texid ); // will be loading later
|
||||
out->image = r_notexture; // make default
|
||||
}
|
||||
|
||||
// count animation frames
|
||||
for (i = 0; i < count; i++)
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
out = &loadmodel->texinfo[i];
|
||||
out->numframes = 1;
|
||||
for (step = out->next; step && step != out; step = step->next)
|
||||
for( step = out->next; step && step != out; step = step->next )
|
||||
out->numframes++;
|
||||
}
|
||||
}
|
||||
|
@ -913,8 +902,9 @@ void Mod_LoadBrushModel (model_t *mod, void *buffer)
|
|||
Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
|
||||
Mod_SetupSubmodels( mod );// set up the submodels
|
||||
|
||||
mod->numframes = 2; // regular and alternate animation
|
||||
mod->registration_sequence = registration_sequence;//register model
|
||||
mod->numframes = 2; // regular and alternate animation
|
||||
mod->registration_sequence = registration_sequence; // register model
|
||||
loadmodel->num_textures = 0; // waiting for load
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -959,16 +949,9 @@ void R_BeginRegistration (char *model)
|
|||
|
||||
// explicitly free the old map if different
|
||||
// this guarantees that mod_known[0] is the world map
|
||||
if(com.strcmp(mod_known[0].name, fullname))
|
||||
{
|
||||
Mod_Free (&mod_known[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// textures already loaded
|
||||
Cvar_SetValue("scr_loading", r_loading->value + 45.0f );
|
||||
}
|
||||
r_worldmodel = Mod_ForName(fullname, true);
|
||||
if( com.strcmp( mod_known[0].name, fullname ))
|
||||
Mod_Free( &mod_known[0] );
|
||||
r_worldmodel = Mod_ForName( fullname, true );
|
||||
|
||||
r_viewcluster = -1;
|
||||
}
|
||||
|
@ -980,7 +963,7 @@ R_RegisterModel
|
|||
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
*/
|
||||
model_t *R_RegisterModel (char *name)
|
||||
model_t *R_RegisterModel (const char *name)
|
||||
{
|
||||
model_t *mod;
|
||||
int i;
|
||||
|
@ -990,6 +973,7 @@ model_t *R_RegisterModel (char *name)
|
|||
{
|
||||
switch(mod->type)
|
||||
{
|
||||
case mod_world:
|
||||
case mod_brush:
|
||||
for (i = 0; i < mod->numtexinfo; i++)
|
||||
mod->texinfo[i].image->registration_sequence = registration_sequence;
|
||||
|
|
|
@ -86,6 +86,7 @@ typedef struct mtexinfo_s
|
|||
int size[2];
|
||||
int flags;
|
||||
int numframes;
|
||||
int texid; // save texture id
|
||||
struct mtexinfo_s *next; // animation chain
|
||||
image_t *image;
|
||||
} mtexinfo_t;
|
||||
|
@ -186,6 +187,7 @@ typedef struct model_s
|
|||
byte *mempool;
|
||||
|
||||
int numframes;
|
||||
int num_textures; // count of textures what a really loaded
|
||||
|
||||
int flags;
|
||||
|
||||
|
@ -266,14 +268,16 @@ typedef struct model_s
|
|||
|
||||
void Mod_Init (void);
|
||||
void Mod_ClearAll (void);
|
||||
model_t *Mod_ForName (char *name, bool crash);
|
||||
model_t *Mod_ForName ( const char *name, bool crash);
|
||||
mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
|
||||
byte *Mod_ClusterPVS (int cluster, model_t *model);
|
||||
const char *Mod_GetStringFromTable( int index );
|
||||
|
||||
void Mod_Modellist_f (void);
|
||||
void Mod_FreeAll (void);
|
||||
void Mod_Free (model_t *mod);
|
||||
|
||||
extern model_t *loadmodel;
|
||||
|
||||
int R_StudioExtractBbox( studiohdr_t *phdr, int sequence, float *mins, float *maxs );
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ byte *r_temppool;
|
|||
int GL_TEXTURE0, GL_TEXTURE1;
|
||||
|
||||
model_t *r_worldmodel;
|
||||
model_t *r_models[MAX_MODELS];
|
||||
|
||||
float gldepthmin, gldepthmax;
|
||||
|
||||
|
@ -47,8 +48,8 @@ image_t *r_particletexture;// little dot for particles
|
|||
image_t *r_radarmap; // wall texture for radar texgen
|
||||
image_t *r_around;
|
||||
|
||||
entity_t *currententity;
|
||||
model_t *currentmodel;
|
||||
ref_entity_t *currententity;
|
||||
model_t *currentmodel;
|
||||
|
||||
cplane_t frustum[4];
|
||||
|
||||
|
@ -77,9 +78,9 @@ float r_base_world_matrix[16];
|
|||
//
|
||||
// screen size info
|
||||
//
|
||||
refdef_t r_newrefdef;
|
||||
refdef_t r_newrefdef; // proceeed refdef
|
||||
|
||||
int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
|
||||
int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;
|
||||
|
||||
cvar_t *r_check_errors;
|
||||
cvar_t *r_norefresh;
|
||||
|
@ -186,7 +187,7 @@ bool R_CullBox (vec3_t mins, vec3_t maxs)
|
|||
}
|
||||
|
||||
|
||||
void R_RotateForEntity (entity_t *e)
|
||||
void R_RotateForEntity( ref_entity_t *e )
|
||||
{
|
||||
pglTranslatef (e->origin[0], e->origin[1], e->origin[2]);
|
||||
|
||||
|
@ -483,7 +484,7 @@ void R_SetFrustum (void)
|
|||
R_SetupFrame
|
||||
===============
|
||||
*/
|
||||
void R_SetupFrame (void)
|
||||
void R_SetupFrame( void )
|
||||
{
|
||||
int i;
|
||||
mleaf_t *leaf;
|
||||
|
@ -540,7 +541,7 @@ void R_SetupFrame (void)
|
|||
{
|
||||
pglEnable( GL_SCISSOR_TEST );
|
||||
pglClearColor( 0.3f, 0.3f, 0.3f, 1 );
|
||||
pglScissor( r_newrefdef.x, r_height->integer - r_newrefdef.height - r_newrefdef.y, r_newrefdef.width, r_newrefdef.height );
|
||||
pglScissor( r_newrefdef.rect.x, r_height->integer - r_newrefdef.rect.height - r_newrefdef.rect.y, r_newrefdef.rect.width, r_newrefdef.rect.height );
|
||||
pglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
pglClearColor( 1, 0, 0.5, 0.5 );
|
||||
pglDisable( GL_SCISSOR_TEST );
|
||||
|
@ -563,10 +564,10 @@ void R_SetupGL (void)
|
|||
//
|
||||
pglMatrixMode( GL_PROJECTION );
|
||||
pglLoadIdentity();
|
||||
x = floor(r_newrefdef.x * r_width->integer / r_width->integer);
|
||||
x2 = ceil((r_newrefdef.x + r_newrefdef.width) * r_width->integer / r_width->integer);
|
||||
y = floor(r_height->integer - r_newrefdef.y * r_height->integer / r_height->integer);
|
||||
y2 = ceil(r_height->integer - (r_newrefdef.y + r_newrefdef.height) * r_height->integer / r_height->integer);
|
||||
x = floor(r_newrefdef.rect.x * r_width->integer / r_width->integer);
|
||||
x2 = ceil((r_newrefdef.rect.x + r_newrefdef.rect.width) * r_width->integer / r_width->integer);
|
||||
y = floor(r_height->integer - r_newrefdef.rect.y * r_height->integer / r_height->integer);
|
||||
y2 = ceil(r_height->integer - (r_newrefdef.rect.y + r_newrefdef.rect.height) * r_height->integer / r_height->integer);
|
||||
|
||||
w = x2 - x;
|
||||
h = y - y2;
|
||||
|
@ -578,8 +579,8 @@ void R_SetupGL (void)
|
|||
//
|
||||
// set up projection matrix
|
||||
//
|
||||
screenaspect = (float)r_newrefdef.width/r_newrefdef.height;
|
||||
// yfov = 2*atan((float)r_newrefdef.height/r_newrefdef.width)*180/M_PI;
|
||||
screenaspect = (float)r_newrefdef.rect.width/r_newrefdef.rect.height;
|
||||
// yfov = 2*atan((float)r_newrefdef.rect.height/r_newrefdef.rect.width)*180/M_PI;
|
||||
|
||||
pglPerspective (r_newrefdef.fov_y, screenaspect, 4, 131072 );
|
||||
|
||||
|
@ -886,7 +887,7 @@ void R_SetGL2D( void )
|
|||
n = R_DrawRSpeeds(S);
|
||||
pglColor4f(1, 0, 1, 1);
|
||||
for (i = 0; i < n; i++)
|
||||
Draw_Char(r_newrefdef.width - 60 + ((i - n) * 8), r_newrefdef.height - 60, 128 + S[i]);
|
||||
Draw_Char(r_newrefdef.rect.width - 60 + ((i - n) * 8), r_newrefdef.rect.height - 60, 128 + S[i]);
|
||||
pglColor4f (1, 1, 1, 1);
|
||||
}
|
||||
|
||||
|
@ -928,13 +929,155 @@ void R_SetLightLevel (void)
|
|||
|
||||
}
|
||||
|
||||
static bool R_AddEntityToScene( refdef_t *fd, entity_state_t *s1, entity_state_t *s2, float lerpfrac )
|
||||
{
|
||||
uint i, effects;
|
||||
ref_entity_t *refent;
|
||||
int max_edicts = Cvar_VariableValue( "prvm_maxedicts" );
|
||||
|
||||
if( !fd || !fd->entities ) return false; // not init
|
||||
if( !s1 || !s1->model.index ) return false; // if set to invisible, skip
|
||||
|
||||
if( fd->num_entities >= max_edicts )
|
||||
return false;
|
||||
|
||||
refent = &fd->entities[fd->num_entities];
|
||||
if( !s2 ) s2 = s1; // no lerping state
|
||||
|
||||
effects = s1->effects;
|
||||
refent->frame = s1->model.frame;
|
||||
|
||||
// copy state to render
|
||||
refent->prev.frame = s2->model.frame;
|
||||
refent->backlerp = 1.0f - lerpfrac;
|
||||
refent->alpha = s1->renderamt;
|
||||
refent->body = s1->model.body;
|
||||
refent->sequence = s1->model.sequence;
|
||||
refent->animtime = s1->model.animtime;
|
||||
|
||||
// setup latchedvars
|
||||
refent->prev.animtime = s2->model.animtime;
|
||||
VectorCopy( s2->origin, refent->prev.origin );
|
||||
VectorCopy( s2->angles, refent->prev.angles );
|
||||
refent->prev.sequence = s2->model.sequence;
|
||||
refent->prev.frame = s2->model.frame;
|
||||
//refent->prev.sequencetime;
|
||||
|
||||
// interpolate origin
|
||||
for( i = 0; i < 3; i++ )
|
||||
refent->origin[i] = refent->oldorigin[i] = LerpPoint( s2->origin[i], s1->origin[i], lerpfrac );
|
||||
|
||||
// set skin
|
||||
refent->skin = s1->model.skin;
|
||||
refent->model = r_models[s1->model.index];
|
||||
refent->weaponmodel = r_models[s1->pmodel.index];
|
||||
refent->flags = s1->renderfx;
|
||||
|
||||
// calculate angles
|
||||
if( effects & EF_ROTATE )
|
||||
{
|
||||
// some bonus items auto-rotate
|
||||
VectorSet( refent->angles, 0, anglemod(fd->time / 10), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// interpolate angles
|
||||
for( i = 0; i < 3; i++ )
|
||||
refent->angles[i] = LerpAngle( s2->angles[i], s1->angles[i], lerpfrac );
|
||||
}
|
||||
|
||||
// copy controllers
|
||||
for( i = 0; i < MAXSTUDIOCONTROLLERS; i++ )
|
||||
{
|
||||
refent->controller[i] = s1->model.controller[i];
|
||||
refent->prev.controller[i] = s2->model.controller[i];
|
||||
}
|
||||
|
||||
// copy blends
|
||||
for( i = 0; i < MAXSTUDIOBLENDS; i++ )
|
||||
{
|
||||
refent->blending[i] = s1->model.blending[i];
|
||||
refent->prev.blending[i] = s2->model.blending[i];
|
||||
}
|
||||
|
||||
if( s1->ed_type == ED_CLIENT )
|
||||
{
|
||||
refent->flags |= RF_PLAYERMODEL; // only draw from mirrors
|
||||
|
||||
// just only for test
|
||||
refent->controller[0] = refent->controller[1] = 90.0;
|
||||
refent->controller[2] = refent->controller[3] = 180.0;
|
||||
refent->sequence = 0;
|
||||
refent->frame = 0;
|
||||
}
|
||||
|
||||
// add entity
|
||||
fd->num_entities++;
|
||||
r_newrefdef = *fd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool R_AddParticleToChain( refdef_t *fd, vec3_t org, float alpha, int color )
|
||||
{
|
||||
particle_t *p;
|
||||
|
||||
if( !fd || !fd->particles ) return false;
|
||||
if( fd->num_particles >= MAX_PARTICLES)
|
||||
return false;
|
||||
|
||||
p = &fd->particles[fd->num_particles];
|
||||
VectorCopy( org, p->origin );
|
||||
p->color = color;
|
||||
p->alpha = alpha;
|
||||
fd->num_particles++;
|
||||
r_newrefdef = *fd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool R_AddLightStyle( refdef_t *fd, int style, vec3_t color )
|
||||
{
|
||||
lightstyle_t *ls;
|
||||
|
||||
if( !fd || !fd->lightstyles ) return false;
|
||||
if( style < 0 || style > MAX_LIGHTSTYLES )
|
||||
return false; // invalid lightstyle
|
||||
|
||||
ls = &fd->lightstyles[style];
|
||||
ls->white = color[0] + color[1] + color[2];
|
||||
VectorCopy( color, ls->rgb );
|
||||
r_newrefdef = *fd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool R_AddDynamicLight( refdef_t *fd, vec3_t org, vec3_t color, float intensity )
|
||||
{
|
||||
dlight_t *dl;
|
||||
|
||||
if( !fd || !fd->dlights ) return false;
|
||||
if( fd->num_dlights >= MAX_DLIGHTS )
|
||||
return false;
|
||||
|
||||
dl = &fd->dlights[fd->num_dlights];
|
||||
VectorCopy( org, dl->origin );
|
||||
VectorCopy( color, dl->color );
|
||||
dl->intensity = intensity;
|
||||
fd->num_dlights++;
|
||||
r_newrefdef = *fd;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
R_RenderFrame
|
||||
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
*/
|
||||
void R_RenderFrame (refdef_t *fd)
|
||||
void R_RenderFrame( refdef_t *fd )
|
||||
{
|
||||
r_mirroralpha->value = bound( 0.0f, r_mirroralpha->value, 1.0f );
|
||||
mirror = false;
|
||||
|
@ -943,9 +1086,8 @@ void R_RenderFrame (refdef_t *fd)
|
|||
R_RenderView( fd );
|
||||
if( mirror ) R_Mirror( fd );
|
||||
GL_DrawRadar( fd );
|
||||
R_SetLightLevel ();
|
||||
//Sys_Break("Render Frame\n");
|
||||
R_SetGL2D ();
|
||||
R_SetLightLevel();
|
||||
R_SetGL2D();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1017,17 +1159,17 @@ void R_BeginFrame( void )
|
|||
|
||||
// go into 2D mode
|
||||
pglDrawBuffer( GL_BACK );
|
||||
pglViewport (0,0, r_width->integer, r_height->integer);
|
||||
pglMatrixMode(GL_PROJECTION);
|
||||
pglLoadIdentity ();
|
||||
pglOrtho (0, r_width->integer, r_height->integer, 0, -99999, 99999);
|
||||
pglMatrixMode(GL_MODELVIEW);
|
||||
pglLoadIdentity ();
|
||||
pglDisable (GL_DEPTH_TEST);
|
||||
pglDisable (GL_CULL_FACE);
|
||||
pglViewport( 0, 0, r_width->integer, r_height->integer );
|
||||
pglMatrixMode( GL_PROJECTION );
|
||||
pglLoadIdentity();
|
||||
pglOrtho ( 0, r_width->integer, r_height->integer, 0, -99999, 99999 );
|
||||
pglMatrixMode( GL_MODELVIEW );
|
||||
pglLoadIdentity();
|
||||
pglDisable( GL_DEPTH_TEST );
|
||||
pglDisable( GL_CULL_FACE );
|
||||
GL_DisableBlend();
|
||||
GL_EnableAlphaTest();
|
||||
pglColor4f (1,1,1,1);
|
||||
pglColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
|
||||
/*
|
||||
** draw buffer stuff
|
||||
|
@ -1078,6 +1220,38 @@ void R_EndFrame( void )
|
|||
}
|
||||
}
|
||||
|
||||
void R_ClearScene( refdef_t *fd )
|
||||
{
|
||||
if( !fd ) return;
|
||||
|
||||
if( !fd->mempool )
|
||||
{
|
||||
// init arrays
|
||||
if( fd->rdflags & RDF_NOWORLDMODEL )
|
||||
{
|
||||
// menu viewport not needs to many objects
|
||||
fd->mempool = Mem_AllocPool( "Viewport Zone" );
|
||||
fd->entities = (ref_entity_t *)Mem_Alloc( fd->mempool, sizeof(ref_entity_t) * 32 );
|
||||
fd->particles = (particle_t *)Mem_Alloc( fd->mempool, sizeof(particle_t) * 512 );
|
||||
fd->dlights = (dlight_t *)Mem_Alloc( fd->mempool, sizeof(dlight_t) * 4 );
|
||||
}
|
||||
else
|
||||
{
|
||||
fd->mempool = Mem_AllocPool("Refdef Zone");
|
||||
fd->entities = (ref_entity_t *)Mem_Alloc( fd->mempool, sizeof(ref_entity_t) * Cvar_VariableValue("prvm_maxedicts"));
|
||||
fd->particles = (particle_t *)Mem_Alloc( fd->mempool, sizeof(particle_t) * MAX_PARTICLES );
|
||||
fd->lightstyles = (lightstyle_t *)Mem_Alloc( fd->mempool, sizeof(lightstyle_t) * MAX_LIGHTSTYLES );
|
||||
fd->dlights = (dlight_t *)Mem_Alloc( fd->mempool, sizeof(dlight_t) * MAX_DLIGHTS );
|
||||
}
|
||||
}
|
||||
|
||||
// clear scene
|
||||
fd->num_dlights = 0;
|
||||
fd->num_entities = 0;
|
||||
fd->num_particles = 0;
|
||||
r_newrefdef = *fd;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
R_SetPalette
|
||||
|
@ -1117,27 +1291,44 @@ void R_SetPalette ( const byte *palette)
|
|||
pglClearColor (1, 0, 0.5, 0.5);
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
R_RegisterSkin
|
||||
===============
|
||||
*/
|
||||
image_t *R_RegisterSkin (char *name)
|
||||
{
|
||||
return R_FindImage (name, NULL, 0, it_skin);
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
||||
|
||||
void R_BeginRegistration (char *map);
|
||||
model_t *R_RegisterModel (char *name);
|
||||
void R_SetSky (char *name, float rotate, vec3_t axis);
|
||||
void R_EndRegistration (void);
|
||||
bool R_UploadModel( const char *name, int index )
|
||||
{
|
||||
model_t *mod;
|
||||
|
||||
void R_RenderFrame (refdef_t *fd);
|
||||
// this array used by AddEntityToScene
|
||||
mod = R_RegisterModel( name );
|
||||
r_models[index] = mod;
|
||||
|
||||
image_t *Draw_FindPic (char *name);
|
||||
return (mod != NULL);
|
||||
}
|
||||
|
||||
bool R_UploadImage( const char *name, int index )
|
||||
{
|
||||
string filename;
|
||||
image_t *texture;
|
||||
|
||||
// nothing to load
|
||||
if( !r_worldmodel ) return false;
|
||||
loadmodel = r_worldmodel;
|
||||
|
||||
// all textures are loaded
|
||||
if( !com.strcmp( loadmodel->name, name ) && loadmodel->num_textures == loadmodel->numtexinfo )
|
||||
return false;
|
||||
|
||||
com.strncpy( filename, Mod_GetStringFromTable( loadmodel->texinfo[index].texid ), sizeof(filename));
|
||||
texture = R_FindImage( filename, NULL, 0, it_wall );
|
||||
|
||||
if(!texture) Msg("returned null image!\n");
|
||||
if(texture == r_notexture ) Msg("returned r_notexture!\n");
|
||||
|
||||
if( texture ) loadmodel->texinfo[index].image = texture;
|
||||
loadmodel->num_textures++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@@@@@@@@@@@@@@@@@@@@
|
||||
|
@ -1153,7 +1344,7 @@ render_exp_t DLLEXPORT *CreateAPI(stdlib_api_t *input, render_imp_t *engfuncs )
|
|||
// Sys_LoadLibrary can create fake instance, to check
|
||||
// api version and api size, but second argument will be 0
|
||||
// and always make exception, run simply check for avoid it
|
||||
if(engfuncs) ri = *engfuncs;
|
||||
if( engfuncs ) ri = *engfuncs;
|
||||
|
||||
// generic functions
|
||||
re.api_size = sizeof(render_exp_t);
|
||||
|
@ -1162,12 +1353,18 @@ render_exp_t DLLEXPORT *CreateAPI(stdlib_api_t *input, render_imp_t *engfuncs )
|
|||
re.Shutdown = R_Shutdown;
|
||||
|
||||
re.BeginRegistration = R_BeginRegistration;
|
||||
re.RegisterModel = R_RegisterModel;
|
||||
re.RegisterSkin = R_RegisterSkin;
|
||||
re.RegisterModel = R_UploadModel;
|
||||
re.RegisterImage = R_UploadImage;
|
||||
re.RegisterPic = Draw_FindPic;
|
||||
re.SetSky = R_SetSky;
|
||||
re.EndRegistration = R_EndRegistration;
|
||||
|
||||
re.AddLightStyle = R_AddLightStyle;
|
||||
re.AddRefEntity = R_AddEntityToScene;
|
||||
re.AddDynLight = R_AddDynamicLight;
|
||||
re.AddParticle = R_AddParticleToChain;
|
||||
re.ClearScene = R_ClearScene;
|
||||
|
||||
re.BeginFrame = R_BeginFrame;
|
||||
re.RenderFrame = R_RenderFrame;
|
||||
re.EndFrame = R_EndFrame;
|
||||
|
|
|
@ -19,7 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
*/
|
||||
// r_misc.c
|
||||
|
||||
#include <time.h>
|
||||
#include "gl_local.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -884,7 +884,7 @@ void R_DrawBrushModel ( int passnum )
|
|||
vec3_t mins, maxs;
|
||||
int i;
|
||||
bool rotated;
|
||||
entity_t *e = currententity;
|
||||
ref_entity_t *e = currententity;
|
||||
|
||||
if ( (e->flags & RF_TRANSLUCENT) && (passnum == RENDERPASS_SOLID)) return;// solid
|
||||
if (!(e->flags & RF_TRANSLUCENT) && (passnum == RENDERPASS_ALPHA)) return;// solid
|
||||
|
@ -1141,7 +1141,7 @@ R_DrawWorld
|
|||
*/
|
||||
void R_DrawWorld (void)
|
||||
{
|
||||
entity_t ent;
|
||||
ref_entity_t ent;
|
||||
|
||||
if (!r_drawworld->value)
|
||||
return;
|
||||
|
@ -1396,20 +1396,20 @@ GL_BuildPolygonFromSurface
|
|||
*/
|
||||
void GL_BuildPolygonFromSurface(msurface_t *fa)
|
||||
{
|
||||
int i, lindex, lnumverts;
|
||||
int i, lindex, lnumverts;
|
||||
medge_t *pedges, *r_pedge;
|
||||
int vertpage;
|
||||
int vertpage;
|
||||
float *vec;
|
||||
float s, t;
|
||||
glpoly_t *poly;
|
||||
glpoly_t *poly;
|
||||
vec3_t total;
|
||||
|
||||
// reconstruct the polygon
|
||||
// reconstruct the polygon
|
||||
pedges = currentmodel->edges;
|
||||
lnumverts = fa->numedges;
|
||||
vertpage = 0;
|
||||
|
||||
VectorClear (total);
|
||||
VectorClear( total );
|
||||
//
|
||||
// draw texture
|
||||
//
|
||||
|
@ -1419,11 +1419,11 @@ void GL_BuildPolygonFromSurface(msurface_t *fa)
|
|||
fa->polys = poly;
|
||||
poly->numverts = lnumverts;
|
||||
|
||||
for (i=0 ; i<lnumverts ; i++)
|
||||
for( i = 0; i < lnumverts; i++ )
|
||||
{
|
||||
lindex = currentmodel->surfedges[fa->firstedge + i];
|
||||
|
||||
if (lindex > 0)
|
||||
if( lindex > 0 )
|
||||
{
|
||||
r_pedge = &pedges[lindex];
|
||||
vec = currentmodel->vertexes[r_pedge->v[0]].position;
|
||||
|
@ -1433,8 +1433,8 @@ void GL_BuildPolygonFromSurface(msurface_t *fa)
|
|||
r_pedge = &pedges[-lindex];
|
||||
vec = currentmodel->vertexes[r_pedge->v[1]].position;
|
||||
}
|
||||
s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
|
||||
if(fa->texinfo->size[0] != -1) s /= fa->texinfo->size[0];
|
||||
s = DotProduct( vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
|
||||
if( fa->texinfo->size[0] != -1 ) s /= fa->texinfo->size[0];
|
||||
else s /= fa->texinfo->image->width;
|
||||
|
||||
t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
|
||||
|
|
|
@ -429,21 +429,21 @@ void R_BloomBlend ( refdef_t *fd )
|
|||
pglColor4f( 1, 1, 1, 1 );
|
||||
|
||||
//set up current sizes
|
||||
curView_x = fd->x;
|
||||
curView_y = fd->y;
|
||||
curView_width = fd->width;
|
||||
curView_height = fd->height;
|
||||
screenText_tcw = ((float)fd->width / (float)screen_texture_width);
|
||||
screenText_tch = ((float)fd->height / (float)screen_texture_height);
|
||||
if( fd->height > fd->width )
|
||||
curView_x = fd->rect.x;
|
||||
curView_y = fd->rect.y;
|
||||
curView_width = fd->rect.width;
|
||||
curView_height = fd->rect.height;
|
||||
screenText_tcw = ((float)fd->rect.width / (float)screen_texture_width);
|
||||
screenText_tch = ((float)fd->rect.height / (float)screen_texture_height);
|
||||
if( fd->rect.height > fd->rect.width )
|
||||
{
|
||||
sampleText_tcw = ((float)fd->width / (float)fd->height);
|
||||
sampleText_tcw = ((float)fd->rect.width / (float)fd->rect.height);
|
||||
sampleText_tch = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleText_tcw = 1.0f;
|
||||
sampleText_tch = ((float)fd->height / (float)fd->width);
|
||||
sampleText_tch = ((float)fd->rect.height / (float)fd->rect.width);
|
||||
}
|
||||
sample_width = BLOOM_SIZE * sampleText_tcw;
|
||||
sample_height = BLOOM_SIZE * sampleText_tch;
|
||||
|
|
100
render/r_local.h
100
render/r_local.h
|
@ -42,6 +42,82 @@ typedef enum
|
|||
R_EXTCOUNT
|
||||
} r_opengl_extensions;
|
||||
|
||||
typedef struct latchedvars_s
|
||||
{
|
||||
float animtime;
|
||||
float sequencetime;
|
||||
vec3_t origin;
|
||||
vec3_t angles;
|
||||
|
||||
int sequence;
|
||||
float frame;
|
||||
|
||||
byte blending[MAXSTUDIOBLENDS];
|
||||
byte seqblending[MAXSTUDIOBLENDS];
|
||||
byte controller[MAXSTUDIOCONTROLLERS];
|
||||
|
||||
} latchedvars_t;
|
||||
|
||||
// client entity
|
||||
typedef struct ref_entity_s
|
||||
{
|
||||
model_t *model; // opaque type outside refresh
|
||||
model_t *weaponmodel; // opaque type outside refresh
|
||||
|
||||
latchedvars_t prev; // previous frame values for lerping
|
||||
|
||||
vec3_t angles;
|
||||
vec3_t origin; // also used as RF_BEAM's "from"
|
||||
float oldorigin[3]; // also used as RF_BEAM's "to"
|
||||
|
||||
float animtime;
|
||||
float frame; // also used as RF_BEAM's diameter
|
||||
float framerate;
|
||||
|
||||
int body;
|
||||
int skin;
|
||||
|
||||
byte blending[MAXSTUDIOBLENDS];
|
||||
byte controller[MAXSTUDIOCONTROLLERS];
|
||||
byte mouth; //TODO: move to struct
|
||||
|
||||
int movetype; //entity moving type
|
||||
int sequence;
|
||||
float scale;
|
||||
|
||||
vec3_t attachment[MAXSTUDIOATTACHMENTS];
|
||||
|
||||
// misc
|
||||
float backlerp; // 0.0 = current, 1.0 = old
|
||||
int skinnum; // also used as RF_BEAM's palette index
|
||||
|
||||
int lightstyle; // for flashing entities
|
||||
float alpha; // ignore if RF_TRANSLUCENT isn't set
|
||||
int flags;
|
||||
|
||||
} ref_entity_t;
|
||||
|
||||
typedef struct lightstyle_s
|
||||
{
|
||||
float rgb[3]; // 0.0 - 2.0
|
||||
float white; // highest of rgb
|
||||
} lightstyle_t;
|
||||
|
||||
typedef struct particle_s
|
||||
{
|
||||
vec3_t origin;
|
||||
int color;
|
||||
float alpha;
|
||||
|
||||
} particle_t;
|
||||
|
||||
typedef struct dlight_s
|
||||
{
|
||||
vec3_t origin;
|
||||
vec3_t color;
|
||||
float intensity;
|
||||
} dlight_t;
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
||||
|
@ -91,21 +167,21 @@ typedef struct glstate_s
|
|||
// setting by R_Init and using as read-only
|
||||
typedef struct glconfig_s
|
||||
{
|
||||
const char *renderer_string;
|
||||
const char *vendor_string;
|
||||
const char *version_string;
|
||||
const char *renderer_string;
|
||||
const char *vendor_string;
|
||||
const char *version_string;
|
||||
|
||||
// list of supported extensions
|
||||
const char *extensions_string;
|
||||
byte extension[R_EXTCOUNT];
|
||||
const char *extensions_string;
|
||||
byte extension[R_EXTCOUNT];
|
||||
|
||||
int textureunits;
|
||||
int max_3d_texture_size;
|
||||
int max_cubemap_texture_size;
|
||||
int max_anisotropy;
|
||||
GLint texRectangle;
|
||||
bool fullscreen;
|
||||
int prev_mode;
|
||||
int textureunits;
|
||||
int max_3d_texture_size;
|
||||
int max_cubemap_texture_size;
|
||||
int max_anisotropy;
|
||||
GLint texRectangle;
|
||||
bool fullscreen;
|
||||
int prev_mode;
|
||||
} glconfig_t;
|
||||
|
||||
#endif//R_LOCAL_H
|
|
@ -12,7 +12,7 @@ cplane_t *mirror_plane;
|
|||
msurface_t *mirrorchain = NULL;
|
||||
bool mirror_render; // true when reflections are being rendered
|
||||
float r_base_world_matrix[16];
|
||||
entity_t *mirror_entity = NULL;
|
||||
ref_entity_t *mirror_entity = NULL;
|
||||
|
||||
void Mirror_Scale( void )
|
||||
{
|
||||
|
|
|
@ -14,6 +14,6 @@ extern bool mirror;
|
|||
extern cplane_t *mirror_plane;
|
||||
extern msurface_t *mirrorchain;
|
||||
extern bool mirror_render;
|
||||
extern entity_t *mirror_entity;
|
||||
extern ref_entity_t *mirror_entity;
|
||||
|
||||
#endif//R_MIRROR_H
|
|
@ -181,7 +181,7 @@ void R_SpriteLoadModel( model_t *mod, void *buffer )
|
|||
R_GetSpriteFrame
|
||||
================
|
||||
*/
|
||||
mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
|
||||
mspriteframe_t *R_GetSpriteFrame( ref_entity_t *currententity )
|
||||
{
|
||||
msprite_t *psprite;
|
||||
mspritegroup_t *pspritegroup;
|
||||
|
@ -231,7 +231,7 @@ mspriteframe_t *R_GetSpriteFrame (entity_t *currententity)
|
|||
return pspriteframe;
|
||||
}
|
||||
|
||||
bool R_AcceptSpritePass( entity_t *e, int pass )
|
||||
bool R_AcceptSpritePass( ref_entity_t *e, int pass )
|
||||
{
|
||||
msprite_t *psprite = (msprite_t *)currentmodel->extradata;
|
||||
|
||||
|
@ -280,7 +280,7 @@ void R_DrawSpriteModel( int passnum )
|
|||
{
|
||||
mspriteframe_t *frame;
|
||||
vec3_t point, forward, right, up;
|
||||
entity_t *e = currententity;
|
||||
ref_entity_t *e = currententity;
|
||||
model_t *mod = currentmodel;
|
||||
float alpha = 1.0f, angle, sr, cr;
|
||||
vec3_t distance;
|
||||
|
|
|
@ -43,7 +43,7 @@ int m_fDoInterp;
|
|||
int m_pStudioModelCount;
|
||||
int m_PassNum;
|
||||
model_t *m_pRenderModel;
|
||||
entity_t *m_pCurrentEntity;
|
||||
ref_entity_t *m_pCurrentEntity;
|
||||
mstudiomodel_t *m_pSubModel;
|
||||
studiohdr_t *m_pStudioHeader;
|
||||
studiohdr_t *m_pTextureHeader;
|
||||
|
@ -531,8 +531,19 @@ void R_StudioSetUpTransform ( void )
|
|||
vec3_t angles, modelpos;
|
||||
|
||||
VectorCopy( m_pCurrentEntity->origin, modelpos );
|
||||
VectorCopy( m_pCurrentEntity->angles, angles );
|
||||
|
||||
|
||||
// g-cont: iolki-palki!!!
|
||||
if( m_pCurrentEntity->flags & RF_VIEWMODEL )
|
||||
{
|
||||
VectorCopy( m_pCurrentEntity->angles, angles );
|
||||
}
|
||||
else
|
||||
{
|
||||
angles[0] = -m_pCurrentEntity->angles[0];
|
||||
angles[1] = m_pCurrentEntity->angles[1];
|
||||
angles[2] = -m_pCurrentEntity->angles[2];
|
||||
}
|
||||
|
||||
// TODO: should really be stored with the entity instead of being reconstructed
|
||||
// TODO: should use a look-up table
|
||||
// TODO: could cache lazily, stored in the entity
|
||||
|
@ -681,7 +692,7 @@ Studio_FxTransform
|
|||
|
||||
====================
|
||||
*/
|
||||
void R_StudioFxTransform( entity_t *ent, matrix3x4 transform )
|
||||
void R_StudioFxTransform( ref_entity_t *ent, matrix3x4 transform )
|
||||
{
|
||||
//TODO: add here some effects :)
|
||||
}
|
||||
|
@ -986,7 +997,7 @@ void R_StudioCalcAttachments( void )
|
|||
static bool R_StudioComputeBBox( vec3_t bbox[8] )
|
||||
{
|
||||
vec3_t vectors[3];
|
||||
entity_t *e = m_pCurrentEntity;
|
||||
ref_entity_t *e = m_pCurrentEntity;
|
||||
vec3_t mins, maxs, tmp, angles;
|
||||
int i, seq = m_pCurrentEntity->sequence;
|
||||
|
||||
|
@ -1315,7 +1326,7 @@ void R_StudioDrawPoints ( void )
|
|||
pglPushMatrix();
|
||||
pglLoadIdentity();
|
||||
pglScalef( -1, 1, 1 );
|
||||
pglPerspective( r_newrefdef.fov_y, ( float ) r_newrefdef.width / r_newrefdef.height, 4, 131072 );
|
||||
pglPerspective( r_newrefdef.fov_y, ( float ) r_newrefdef.rect.width / r_newrefdef.rect.height, 4, 131072 );
|
||||
pglMatrixMode( GL_MODELVIEW );
|
||||
pglCullFace( GL_BACK );
|
||||
}
|
||||
|
@ -1637,7 +1648,7 @@ void R_DrawStudioModel( int passnum )
|
|||
|
||||
if (m_pCurrentEntity->weaponmodel)
|
||||
{
|
||||
entity_t saveent = *m_pCurrentEntity;
|
||||
ref_entity_t saveent = *m_pCurrentEntity;
|
||||
model_t *pweaponmodel = m_pCurrentEntity->weaponmodel;
|
||||
|
||||
m_pStudioHeader = pweaponmodel->phdr;
|
||||
|
|
|
@ -1118,13 +1118,14 @@ image_t *R_FindImage( char *name, const byte *buffer, size_t size, imagetype_t t
|
|||
rgbdata_t *pic = NULL;
|
||||
int i;
|
||||
|
||||
if (!name ) return NULL;
|
||||
if (!name ) return r_notexture;
|
||||
|
||||
// look for it
|
||||
for (i = 0, image = gltextures; i < numgltextures; i++, image++)
|
||||
{
|
||||
if (!strcmp(name, image->name))
|
||||
if (!com.strcmp( name, image->name ))
|
||||
{
|
||||
// prolonge registration
|
||||
image->registration_sequence = registration_sequence;
|
||||
return image;
|
||||
}
|
||||
|
@ -1190,7 +1191,7 @@ image_t *R_LoadImage( char *name, rgbdata_t *pic, imagetype_t type )
|
|||
if( numgltextures == MAX_GLTEXTURES )
|
||||
{
|
||||
MsgDev(D_ERROR, "R_LoadImage: gl_textures limit is out\n");
|
||||
return NULL;
|
||||
return r_notexture;
|
||||
}
|
||||
numgltextures++;
|
||||
}
|
||||
|
|
14
todo.log
14
todo.log
|
@ -10,6 +10,13 @@ SprExplorer
|
|||
fopen завешивает приложение, при попытке создать файл в несуществующей директории. Ну вылетал бы чтоли, или ошибку
|
||||
возвращал.
|
||||
|
||||
TODO LIST
|
||||
Переименовать model_t в rmodel_t, создать typedef int model_t; для виртуальной машины
|
||||
Выбросить нахрен поддержку reqfields
|
||||
Из загрузки текстур сделать RegisterTexture c внутренним индексом, по типу register models
|
||||
создать статичный список для автокомпилитинга комманд и переменныхб и вызывать нужные функции из него
|
||||
|
||||
|
||||
Отложенные задачи:
|
||||
1. Поддержка loop для ogg vorbis
|
||||
2. dpvencoder в common.dll
|
||||
|
@ -17,11 +24,8 @@ fopen
|
|||
4. doom snd extractor (write PCM header 8bit 11kHz, dump data)
|
||||
|
||||
Текущие задачи:
|
||||
0. Исправить отрисовку bbox
|
||||
1. Настроить время на сервере
|
||||
2. Server 60 FPS
|
||||
3. cl.time синхронизировать с sv.time
|
||||
|
||||
0. Имплементация рендерера
|
||||
1. Сжать демки хаффманом ?
|
||||
|
||||
Физика игрока:
|
||||
1. Убрать отскоки от стен
|
||||
|
|
|
@ -1214,7 +1214,7 @@ void PRVM_LoadProgs( const char *filename, int numedfunc, char **ed_func, int nu
|
|||
}
|
||||
else if( vm.prog->progs->crc != vm.prog->filecrc )
|
||||
{
|
||||
PRVM_ERROR("%s: %s system vars have been modified, progdefs.h is out of date %d\n", PRVM_NAME, vm.prog->filecrc );
|
||||
PRVM_ERROR("%s: %s system vars have been modified, progdefs.h is out of date %d\n", PRVM_NAME, filename, vm.prog->filecrc );
|
||||
}
|
||||
else MsgDev(D_LOAD, "%s [^2CRC %d^7]\n", filename, vm.prog->progs->crc );
|
||||
|
||||
|
|
|
@ -551,7 +551,7 @@ word PR_WriteProgdefs( void )
|
|||
|
||||
switch( crc )
|
||||
{
|
||||
case 61861:
|
||||
case 1476:
|
||||
PR_Message("Xash3D unmodified server.dat\n");
|
||||
if(!com.strcmp(progsoutname, "unknown.dat")) com.strcpy(progsoutname, "server.dat");
|
||||
break;
|
||||
|
|
Reference in New Issue