03 Aug 2008

This commit is contained in:
g-cont 2008-08-03 00:00:00 +04:00 committed by Alibek Omarov
parent 8e0617c350
commit c55dc2f0a9
46 changed files with 1285 additions and 1873 deletions

View File

@ -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

View File

@ -1,23 +1,7 @@
/*
Copyright (C) 1997-2001 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// cl_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 );
}
/*

View File

@ -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;

View File

@ -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 ();

View File

@ -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

View File

@ -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;

View File

@ -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 );
}

View File

@ -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 )

View File

@ -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

View File

@ -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();
}
/*

View File

@ -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;
}

View File

@ -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 );

View File

@ -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

View 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 );
//============================================================
//

View File

@ -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 );

View File

@ -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" );

View File

@ -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

View File

@ -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;

View File

@ -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" ))
{

View File

@ -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 ));
}

View File

@ -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 )

View File

@ -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
};

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -454,7 +454,6 @@ void GL_InitBackend( void )
void GL_ShutdownBackend( void )
{
if( r_framebuffer ) Z_Free( r_framebuffer );
GL_RemoveCommands();
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 );
/*
====================================================================

View File

@ -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;

View File

@ -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 );

View File

@ -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;

View File

@ -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"
/*

View File

@ -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];

View File

@ -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;

View File

@ -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

View File

@ -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 )
{

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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++;
}

View File

@ -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. Убрать отскоки от стен

View File

@ -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 );

View File

@ -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;