10 Apr 2011

This commit is contained in:
g-cont 2011-04-10 00:00:00 +04:00 committed by Alibek Omarov
parent ec00dbaee5
commit f3cf85f49d
24 changed files with 427 additions and 597 deletions

View File

@ -14,6 +14,8 @@
#include "dlight.h"
#include "input.h"
#define MAX_FORWARD 6
qboolean CL_IsPlayerIndex( int idx )
{
if( idx > 0 && idx <= cl.maxclients )
@ -21,6 +23,17 @@ qboolean CL_IsPlayerIndex( int idx )
return false;
}
qboolean CL_IsPredicted( void )
{
if( !cl_predict->integer || !cl.frame.valid )
return false;
if(( cls.netchan.outgoing_sequence - cls.netchan.incoming_sequence ) >= ( CL_UPDATE_BACKUP - 1 ))
return false;
return true;
}
/*
=========================================================================
@ -442,16 +455,6 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
// set right current state
ent->curstate = *state;
if( ent->player )
{
clgame.dllFuncs.pfnProcessPlayerState( &frame->playerstate[ent->index-1], &ent->curstate );
frame->playerstate[ent->index-1].number = ent->index;
// fill private structure for local client
if(( ent->index - 1 ) == cl.playernum )
frame->local.playerstate = frame->playerstate[ent->index-1];
}
}
/*
@ -662,10 +665,6 @@ void CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
if( cls.disable_servercount != cl.servercount && cl.video_prepped )
SCR_EndLoadingPlaque(); // get rid of loading plaque
// getting a valid frame message ends the connection process
VectorCopy( player->origin, cl.predicted_origin );
VectorCopy( player->angles, cl.predicted_angles );
}
// update local player states
@ -698,8 +697,6 @@ void CL_ParsePacketEntities( sizebuf_t *msg, qboolean delta )
cl.frame = *newframe;
cl.predict[cl.predictcount & CL_UPDATE_MASK] = cl.frame.local;
CL_CheckPredictionError();
}
/*
@ -709,6 +706,71 @@ INTERPOLATE BETWEEN FRAMES TO GET RENDERING PARMS
==========================================================================
*/
/*
===============
CL_SetIdealPitch
===============
*/
void CL_SetIdealPitch( void )
{
float angleval, sinval, cosval;
vec3_t top, bottom;
float z[MAX_FORWARD];
int i, j;
int step, dir, steps;
pmtrace_t tr;
if( !( cl.frame.local.client.flags & FL_ONGROUND ))
return;
angleval = cl.frame.local.playerstate.angles[YAW] * M_PI * 2 / 360;
SinCos( angleval, &sinval, &cosval );
for( i = 0; i < MAX_FORWARD; i++ )
{
top[0] = cl.frame.local.client.origin[0] + cosval * (i + 3) * 12;
top[1] = cl.frame.local.client.origin[1] + sinval * (i + 3) * 12;
top[2] = cl.frame.local.client.origin[2] + cl.frame.local.client.view_ofs[2];
bottom[0] = top[0];
bottom[1] = top[1];
bottom[2] = top[2] - 160;
// skip any monsters (only world and brush models)
tr = PM_PlayerTrace( clgame.pmove, top, bottom, PM_STUDIO_IGNORE, 2, -1, NULL );
if( tr.allsolid ) return; // looking at a wall, leave ideal the way is was
if( tr.fraction == 1.0f )
return; // near a dropoff
z[i] = top[2] + tr.fraction * (bottom[2] - top[2]);
}
dir = 0;
steps = 0;
for( j = 1; j < i; j++ )
{
step = z[j] - z[j-1];
if( step > -ON_EPSILON && step < ON_EPSILON )
continue;
if( dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ))
return; // mixed changes
steps++;
dir = step;
}
if( !dir )
{
cl.refdef.idealpitch = 0;
return;
}
if( steps < 2 ) return;
cl.refdef.idealpitch = -dir * cl_idealpitchscale->value;
}
/*
===============
CL_AddPacketEntities
@ -756,7 +818,8 @@ void CL_AddEntities( void )
cl.num_custombeams = 0;
clgame.dllFuncs.CAM_Think();
CL_SetIdealPitch ();
clgame.dllFuncs.CAM_Think ();
CL_AddPacketEntities( &cl.frame );
clgame.dllFuncs.pfnCreateEntities();

View File

@ -2401,7 +2401,7 @@ pfnLocalPlayerViewheight
void pfnLocalPlayerViewheight( float *view_ofs )
{
// predicted or smoothed
if( view_ofs ) VectorCopy( cl.predicted_viewofs, view_ofs );
if( view_ofs ) VectorCopy( cl.frame.local.client.view_ofs, view_ofs );
}
/*
@ -3633,7 +3633,9 @@ void CL_UnloadProgs( void )
CL_FreeParticles();
VGui_Shutdown();
clgame.dllFuncs.pfnShutdown();
// NOTE: HLFX 0.5 has strange bug: hanging on exit if no map was loaded
if( !( !Q_stricmp( GI->gamedir, "hlfx" ) && GI->version == 0.5f ))
clgame.dllFuncs.pfnShutdown();
Com_FreeLibrary( clgame.hInstance );
Mem_FreePool( &cls.mempool );

View File

@ -32,7 +32,6 @@ convar_t *cl_lightstyle_lerping;
convar_t *cl_idealpitchscale;
convar_t *cl_solid_players;
convar_t *cl_draw_beams;
convar_t *cl_showmiss;
convar_t *cl_cmdrate;
//
@ -1398,8 +1397,6 @@ void CL_InitLocal( void )
cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0, "disable delta-compression for usercommnds" );
cl_idealpitchscale = Cvar_Get( "cl_idealpitchscale", "0.8", 0, "how much to look up/down slopes and stairs when not using freelook" );
cl_solid_players = Cvar_Get( "cl_solid_players", "1", 0, "Make all players not solid (can't traceline them)" );
cl_showmiss = Cvar_Get( "cl_showmiss", "0", CVAR_ARCHIVE, "client show prediction errors" );
cl_timeout = Cvar_Get( "cl_timeout", "60", 0, "connect timeout (in-seconds)" );
rcon_client_password = Cvar_Get( "rcon_password", "", 0, "remote control client password" );

View File

@ -877,7 +877,7 @@ static ui_enginefuncs_t gEngfuncs =
Con_DefaultColor,
pfnGetPlayerModel,
pfnSetPlayerModel,
V_ClearScene,
R_ClearScene,
pfnRenderScene,
CL_AddEntity,
Host_Error,

View File

@ -97,7 +97,7 @@ void CL_AddLinksToPmove( void )
{
cl_entity_t *check;
physent_t *pe;
int i, idx;
int i, solid, idx;
for( i = 0; i < cl.frame.num_entities; i++ )
{
@ -115,14 +115,16 @@ void CL_AddLinksToPmove( void )
clgame.pmove->numvisent++;
}
if( check->player )
continue;
// players will be added later
if( check->player ) continue;
// can't collide with zeroed hull
if( VectorIsNull( check->curstate.mins ) && VectorIsNull( check->curstate.maxs ))
continue;
if( check->curstate.solid == SOLID_BSP || check->curstate.solid == SOLID_BBOX || check->curstate.solid == SOLID_SLIDEBOX )
solid = check->curstate.solid;
if( solid == SOLID_BSP || solid == SOLID_BBOX || solid == SOLID_SLIDEBOX )
{
// reserve slots for all the clients
if( clgame.pmove->numphysent < ( MAX_PHYSENTS - cl.maxclients ))
@ -132,7 +134,7 @@ void CL_AddLinksToPmove( void )
clgame.pmove->numphysent++;
}
}
else if( check->curstate.solid == SOLID_NOT && check->curstate.skin != CONTENTS_NONE )
else if( solid == SOLID_NOT && check->curstate.skin != CONTENTS_NONE )
{
if( clgame.pmove->nummoveent < MAX_MOVEENTS )
{
@ -624,4 +626,108 @@ void CL_SetupPMove( playermove_t *pmove, clientdata_t *cd, entity_state_t *state
pmove->cmd = *ucmd; // setup current cmds
Q_strncpy( pmove->physinfo, cd->physinfo, MAX_INFO_STRING );
}
/*
===========
CL_PostRunCmd
Done after running a player command.
===========
*/
void CL_PostRunCmd( usercmd_t *ucmd, int random_seed )
{
local_state_t *from, *to;
// TODO: write real predicting code
from = &cl.predict[cl.predictcount & CL_UPDATE_MASK];
to = &cl.predict[(cl.predictcount + 1) & CL_UPDATE_MASK];
*to = *from;
clgame.dllFuncs.pfnPostRunCmd( from, to, ucmd, clgame.pmove->runfuncs, cl.time, random_seed );
cl.predictcount++;
}
/*
=================
CL_PredictMovement
Sets cl.predicted_origin and cl.predicted_angles
=================
*/
void CL_PredictMovement( void )
{
int frame = 1;
int ack, outgoing_command;
int current_command;
int current_command_mod;
cl_entity_t *player, *viewent;
clientdata_t *cd;
if( cls.state != ca_active ) return;
if( cl.refdef.paused || cls.key_dest == key_menu ) return;
player = CL_GetLocalPlayer ();
viewent = CL_GetEntityByIndex( cl.refdef.viewentity );
cd = &cl.frame.local.client;
if( cls.demoplayback && viewent )
{
// restore viewangles from angles
cl.refdef.cl_viewangles[PITCH] = -viewent->angles[PITCH] * 3;
cl.refdef.cl_viewangles[YAW] = viewent->angles[YAW];
cl.refdef.cl_viewangles[ROLL] = 0; // roll will be computed in view.cpp
}
// unpredicted pure angled values converted into axis
AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );
if( !CL_IsPredicted( ))
{
// run commands even if client predicting is disabled - client expected it
clgame.pmove->runfuncs = true;
CL_PostRunCmd( cl.refdef.cmd, cls.lastoutgoingcommand );
return;
}
ack = cls.netchan.incoming_acknowledged;
outgoing_command = cls.netchan.outgoing_sequence;
ASSERT( cl.refdef.cmd != NULL );
// setup initial pmove state
CL_SetupPMove( clgame.pmove, cd, &player->curstate, cl.refdef.cmd );
clgame.pmove->runfuncs = false;
while( 1 )
{
// we've run too far forward
if( frame >= CL_UPDATE_BACKUP - 1 )
break;
// Incoming_acknowledged is the last usercmd the server acknowledged having acted upon
current_command = ack + frame;
current_command_mod = current_command & CL_UPDATE_MASK;
// we've caught up to the current command.
if( current_command > outgoing_command )
break;
clgame.pmove->cmd = cl.cmds[frame];
// motor!
clgame.dllFuncs.pfnPlayerMove( clgame.pmove, false ); // run frames
clgame.pmove->runfuncs = ( current_command > outgoing_command - 1 ) ? true : false;
frame++;
}
CL_PostRunCmd( cl.refdef.cmd, frame );
// copy results out for rendering
VectorCopy( clgame.pmove->view_ofs, cl.predicted_viewofs );
VectorCopy( clgame.pmove->origin, cl.predicted_origin );
VectorCopy( clgame.pmove->velocity, cl.predicted_velocity );
}

View File

@ -1,247 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// cl_pred.c - client movement prediction
//=======================================================================
#include "common.h"
#include "client.h"
#include "const.h"
#include "pm_local.h"
#include "net_encode.h"
#define MAX_FORWARD 6
qboolean CL_IsPredicted( void )
{
cl_entity_t *player = CL_GetLocalPlayer();
if( !player )
return false;
if( !cl.frame.valid )
return false;
if( cls.netchan.outgoing_sequence - cls.netchan.incoming_sequence >= CL_UPDATE_BACKUP - 1 )
return false;
if( !cl_predict->integer )
return false;
return true;
}
/*
===========
CL_PostRunCmd
Done after running a player command.
===========
*/
void CL_PostRunCmd( usercmd_t *ucmd, int random_seed )
{
local_state_t *from, *to;
// TODO: write real predicting code
from = &cl.predict[cl.predictcount & CL_UPDATE_MASK];
to = &cl.predict[(cl.predictcount + 1) & CL_UPDATE_MASK];
*to = *from;
clgame.dllFuncs.pfnPostRunCmd( from, to, ucmd, clgame.pmove->runfuncs, cl.time, random_seed );
cl.predictcount++;
}
/*
===================
CL_CheckPredictionError
===================
*/
void CL_CheckPredictionError( void )
{
int frame;
vec3_t delta;
float flen;
if( !CL_IsPredicted( )) return;
// calculate the last usercmd_t we sent that the server has processed
frame = cls.netchan.incoming_acknowledged;
frame &= CL_UPDATE_MASK;
// compare what the server returned with what we had predicted it to be
VectorSubtract( cl.frame.local.client.origin, cl.predicted_origins[frame], delta );
// save the prediction error for interpolation
flen = fabs( delta[0] ) + fabs( delta[1] ) + fabs( delta[2] );
if( flen > 80 )
{
// a teleport or something
VectorClear( cl.prediction_error );
}
else
{
if( cl_showmiss->integer && flen > 0.1f ) Msg( "prediction miss: %g\n", flen );
VectorCopy( cl.frame.local.client.origin, cl.predicted_origins[frame] );
// save for error itnerpolation
VectorCopy( delta, cl.prediction_error );
}
}
/*
===============
CL_SetIdealPitch
===============
*/
void CL_SetIdealPitch( cl_entity_t *ent )
{
float angleval, sinval, cosval;
pmtrace_t tr;
vec3_t top, bottom;
float z[MAX_FORWARD];
int i, j;
int step, dir, steps;
if( !( cl.frame.local.client.flags & FL_ONGROUND ))
return;
angleval = ent->angles[YAW] * M_PI * 2 / 360;
SinCos( angleval, &sinval, &cosval );
for( i = 0; i < MAX_FORWARD; i++ )
{
top[0] = ent->origin[0] + cosval * (i + 3) * 12;
top[1] = ent->origin[1] + sinval * (i + 3) * 12;
top[2] = ent->origin[2] + cl.frame.local.client.view_ofs[2];
bottom[0] = top[0];
bottom[1] = top[1];
bottom[2] = top[2] - 160;
// skip any monsters (only world and brush models)
tr = PM_PlayerTrace( clgame.pmove, top, bottom, PM_STUDIO_IGNORE, 2, -1, NULL );
if( tr.allsolid ) return; // looking at a wall, leave ideal the way is was
if( tr.fraction == 1.0f )
return; // near a dropoff
z[i] = top[2] + tr.fraction * (bottom[2] - top[2]);
}
dir = 0;
steps = 0;
for( j = 1; j < i; j++ )
{
step = z[j] - z[j-1];
if( step > -ON_EPSILON && step < ON_EPSILON )
continue;
if( dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ))
return; // mixed changes
steps++;
dir = step;
}
if( !dir )
{
cl.refdef.idealpitch = 0;
return;
}
if( steps < 2 ) return;
cl.refdef.idealpitch = -dir * cl_idealpitchscale->value;
}
/*
=================
CL_PredictMovement
Sets cl.predicted_origin and cl.predicted_angles
=================
*/
void CL_PredictMovement( void )
{
int frame = 1;
int ack, outgoing_command;
int current_command;
int current_command_mod;
cl_entity_t *player, *viewent;
clientdata_t *cd;
if( cls.state != ca_active ) return;
if( cl.refdef.paused || cls.key_dest == key_menu ) return;
player = CL_GetLocalPlayer ();
viewent = CL_GetEntityByIndex( cl.refdef.viewentity );
cd = &cl.frame.local.client;
CL_SetIdealPitch( player );
if( cls.demoplayback && viewent )
{
// restore viewangles from angles
cl.refdef.cl_viewangles[PITCH] = -viewent->angles[PITCH] * 3;
cl.refdef.cl_viewangles[YAW] = viewent->angles[YAW];
cl.refdef.cl_viewangles[ROLL] = 0; // roll will be computed in view.cpp
}
// unpredicted pure angled values converted into axis
AngleVectors( cl.refdef.cl_viewangles, cl.refdef.forward, cl.refdef.right, cl.refdef.up );
if( !CL_IsPredicted( ))
{
// run commands even if client predicting is disabled - client expected it
clgame.pmove->runfuncs = true;
VectorCopy( cl.refdef.cl_viewangles, cl.predicted_angles );
VectorCopy( cd->view_ofs, cl.predicted_viewofs );
CL_PostRunCmd( cl.refdef.cmd, cls.lastoutgoingcommand );
return;
}
ack = cls.netchan.incoming_acknowledged;
outgoing_command = cls.netchan.outgoing_sequence;
ASSERT( cl.refdef.cmd != NULL );
// setup initial pmove state
CL_SetupPMove( clgame.pmove, cd, &player->curstate, cl.refdef.cmd );
clgame.pmove->runfuncs = false;
while( 1 )
{
// we've run too far forward
if( frame >= CL_UPDATE_BACKUP - 1 )
break;
// Incoming_acknowledged is the last usercmd the server acknowledged having acted upon
current_command = ack + frame;
current_command_mod = current_command & CL_UPDATE_MASK;
// we've caught up to the current command.
if( current_command > outgoing_command )
break;
clgame.pmove->cmd = cl.cmds[frame];
// motor!
clgame.dllFuncs.pfnPlayerMove( clgame.pmove, false ); // run frames
// save for debug checking
VectorCopy( clgame.pmove->origin, cl.predicted_origins[frame-1] );
clgame.pmove->runfuncs = true;
frame++;
}
CL_PostRunCmd( cl.refdef.cmd, frame );
// copy results out for rendering
VectorCopy( clgame.pmove->view_ofs, cl.predicted_viewofs );
VectorCopy( clgame.pmove->origin, cl.predicted_origin );
VectorCopy( clgame.pmove->angles, cl.predicted_angles );
VectorCopy( clgame.pmove->velocity, cl.predicted_velocity );
}

View File

@ -9,9 +9,7 @@
#include "vgui_draw.h"
#include "qfont.h"
convar_t *scr_viewsize;
convar_t *scr_centertime;
convar_t *scr_printspeed;
convar_t *scr_loading;
convar_t *scr_download;
convar_t *scr_width;
@ -22,7 +20,7 @@ convar_t *cl_levelshot_name;
convar_t *cl_envshot_size;
convar_t *scr_dark;
static qboolean scr_init = false;
static qboolean scr_init = false;
/*
==============
@ -69,6 +67,13 @@ void SCR_DrawFPS( void )
Con_DrawString( scr_width->integer - 68, 4, fpsstring, color );
}
/*
==============
SCR_NetSpeeds
same as r_speeds but for network channel
==============
*/
void SCR_NetSpeeds( void )
{
static char msg[MAX_SYSPATH];
@ -116,6 +121,7 @@ void SCR_NetSpeeds( void )
MakeRGBA( color, 255, 255, 255, 255 );
p = start = msg;
do
{
end = Q_strchr( p, '\n' );
@ -230,10 +236,9 @@ SCR_BeginLoadingPlaque
void SCR_BeginLoadingPlaque( qboolean is_background )
{
S_StopAllSounds();
cl.audio_prepped = false; // don't play ambients
cl.audio_prepped = false; // don't play ambients
if( cls.disable_screen ) return; // already set
// if( cl_allow_levelshots->integer ) return; // we want to update screen
if( cls.state == ca_disconnected ) return; // if at console, don't bring up the plaque
if( cls.key_dest == key_console ) return;
@ -241,7 +246,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
SCR_UpdateScreen();
cls.disable_screen = host.realtime;
cls.disable_servercount = cl.servercount;
cl.background = is_background; // set right state before svc_serverdata
cl.background = is_background; // set right state before svc_serverdata is came
}
/*
@ -265,64 +270,65 @@ text to the screen.
*/
void SCR_UpdateScreen( void )
{
if( V_PreRender( ))
if( !V_PreRender( )) return;
switch( cls.state )
{
switch( cls.state )
{
case ca_disconnected:
break;
case ca_connecting:
case ca_connected:
SCR_DrawPlaque();
break;
case ca_active:
V_RenderView();
break;
case ca_cinematic:
SCR_DrawCinematic();
break;
default:
Host_Error( "SCR_UpdateScreen: bad cls.state\n" );
break;
}
V_PostRender();
}
case ca_disconnected:
break;
case ca_connecting:
case ca_connected:
SCR_DrawPlaque();
break;
case ca_active:
V_RenderView();
break;
case ca_cinematic:
SCR_DrawCinematic();
break;
default:
Host_Error( "SCR_UpdateScreen: bad cls.state\n" );
break;
}
V_PostRender();
}
static void SCR_LoadCreditsFont( void )
{
// setup creditsfont
if( FS_FileExists( "gfx/creditsfont.fnt", false ))
{
byte *buffer;
size_t length;
int fontWidth;
qfont_t *src;
// half-life font with variable chars witdh
buffer = FS_LoadFile( "gfx/creditsfont.fnt", &length, false );
R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture );
if( buffer && length >= sizeof( qfont_t ))
{
int i;
src = (qfont_t *)buffer;
clgame.scrInfo.iCharHeight = src->rowheight;
byte *buffer;
size_t length;
int fontWidth;
qfont_t *src;
// build rectangles
for( i = 0; i < 256; i++ )
{
cls.creditsFont.fontRc[i].left = (word)src->fontinfo[i].startoffset % fontWidth;
cls.creditsFont.fontRc[i].right = cls.creditsFont.fontRc[i].left + src->fontinfo[i].charwidth;
cls.creditsFont.fontRc[i].top = (word)src->fontinfo[i].startoffset / fontWidth;
cls.creditsFont.fontRc[i].bottom = cls.creditsFont.fontRc[i].top + src->rowheight;
clgame.scrInfo.charWidths[i] = src->fontinfo[i].charwidth;
}
cls.creditsFont.valid = true;
// setup creditsfont
if( !FS_FileExists( "gfx/creditsfont.fnt", false ))
return;
// half-life font with variable chars witdh
buffer = FS_LoadFile( "gfx/creditsfont.fnt", &length, false );
R_GetTextureParms( &fontWidth, NULL, cls.creditsFont.hFontTexture );
if( buffer && length >= sizeof( qfont_t ))
{
int i;
src = (qfont_t *)buffer;
clgame.scrInfo.iCharHeight = src->rowheight;
// build rectangles
for( i = 0; i < 256; i++ )
{
cls.creditsFont.fontRc[i].left = (word)src->fontinfo[i].startoffset % fontWidth;
cls.creditsFont.fontRc[i].right = cls.creditsFont.fontRc[i].left + src->fontinfo[i].charwidth;
cls.creditsFont.fontRc[i].top = (word)src->fontinfo[i].startoffset / fontWidth;
cls.creditsFont.fontRc[i].bottom = cls.creditsFont.fontRc[i].top + src->rowheight;
clgame.scrInfo.charWidths[i] = src->fontinfo[i].charwidth;
}
if( buffer ) Mem_Free( buffer );
cls.creditsFont.valid = true;
}
if( buffer ) Mem_Free( buffer );
}
static void SCR_InstallParticlePalette( void )
@ -330,8 +336,10 @@ static void SCR_InstallParticlePalette( void )
rgbdata_t *pic;
int i;
pic = FS_LoadImage( "gfx/palette.pal", NULL, 0 );
// NOTE: imagelib required this fakebuffer for loading internal palette
pic = FS_LoadImage( "#valve.pal", ((byte *)&i), 768 );
if( !pic ) pic = FS_LoadImage( "#valve.pal", ((byte *)&i), 768 );
if( pic )
{
@ -409,7 +417,6 @@ void SCR_Init( void )
MsgDev( D_NOTE, "SCR_Init()\n" );
scr_centertime = Cvar_Get( "scr_centertime", "2.5", 0, "centerprint hold time" );
scr_printspeed = Cvar_Get( "scr_printspeed", "8", 0, "centerprint speed of print" );
cl_levelshot_name = Cvar_Get( "cl_levelshot_name", "*black", 0, "contains path to current levelshot" );
cl_allow_levelshots = Cvar_Get( "allow_levelshots", "0", CVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" );
scr_loading = Cvar_Get( "scr_loading", "0", 0, "loading bar progress" );

View File

@ -69,9 +69,7 @@ void CL_ClearTempEnts( void )
if( !cl_tempents ) return;
for( i = 0; i < GI->max_tents - 1; i++ )
{
cl_tempents[i].next = &cl_tempents[i+1];
}
cl_tempents[GI->max_tents-1].next = NULL;
cl_free_tents = cl_tempents;
@ -86,7 +84,8 @@ CL_FreeTempEnts
*/
void CL_FreeTempEnts( void )
{
if( cl_tempents ) Mem_Free( cl_tempents );
if( cl_tempents )
Mem_Free( cl_tempents );
cl_tempents = NULL;
}
@ -104,7 +103,7 @@ void CL_PrepareTEnt( TEMPENTITY *pTemp, model_t *pmodel )
Q_memset( pTemp, 0, sizeof( *pTemp ));
// Use these to set per-frame and termination conditions / actions
// use these to set per-frame and termination conditions / actions
pTemp->flags = FTENT_NONE;
pTemp->die = cl.time + 0.75f;
@ -444,7 +443,7 @@ void CL_FizzEffect( cl_entity_t *pent, int modelIndex, int density )
xspeed *= speed;
yspeed *= speed;
}
else xspeed = yspeed = 0.0f; // zonly
else xspeed = yspeed = 0.0f; // z only
Mod_GetFrames( modelIndex, &frameCount );
@ -516,7 +515,7 @@ void CL_Bubbles( const vec3_t mins, const vec3_t maxs, float height, int modelIn
// Set sprite scale
pTemp->entity.curstate.scale = 1.0f / Com_RandomFloat( 4.0f, 16.0f );
pTemp->entity.curstate.rendermode = kRenderTransAlpha;
pTemp->entity.curstate.renderamt = pTemp->entity.baseline.renderamt = 192; // g-cont. why difference with FizzEffect ???
pTemp->entity.curstate.renderamt = pTemp->entity.baseline.renderamt = 192; // g-cont. why difference with FizzEffect ???
}
}
@ -576,9 +575,9 @@ void CL_AttachTentToPlayer( int client, int modelIndex, float zoffset, float lif
vec3_t position;
cl_entity_t *pClient;
if ( client <= 0 || client > cl.maxclients )
if( client <= 0 || client > cl.maxclients )
{
MsgDev( D_INFO, "Bad client in AttachTentToPlayer()!\n" );
MsgDev( D_ERROR, "Bad client %i in AttachTentToPlayer()!\n", client );
return;
}
@ -645,7 +644,7 @@ void CL_KillAttachedTents( int client )
if( client <= 0 || client > cl.maxclients )
{
MsgDev( D_INFO, "Bad client in KillAttachedTents()!\n" );
MsgDev( D_ERROR, "Bad client %i in KillAttachedTents()!\n", client );
return;
}
@ -787,7 +786,7 @@ void CL_BloodSprite( const vec3_t org, int colorIndex, int modelIndex, int model
if( Mod_GetType( modelIndex ) == mod_bad )
return;
// Large, single blood sprite is a high-priority tent
// large, single blood sprite is a high-priority tent
if(( pTemp = CL_TempEntAllocHigh( org, Mod_Handle( modelIndex ))) != NULL )
{
int i, frameCount;
@ -823,7 +822,7 @@ void CL_BloodSprite( const vec3_t org, int colorIndex, int modelIndex, int model
VectorMA( offset, Com_RandomFloat( -0.5f, 0.5f ) * size, right, offset );
VectorMA( offset, Com_RandomFloat( -0.5f, 0.5f ) * size, up, offset );
pTemp = CL_TempEntAllocHigh( org, Mod_Handle( modelIndex2 ));
pTemp = CL_TempEntAlloc( org, Mod_Handle( modelIndex2 ));
if( !pTemp ) return;
pTemp->flags = FTENT_SPRANIMATELOOP|FTENT_COLLIDEWORLD|FTENT_SLOWGRAVITY;
@ -835,7 +834,7 @@ void CL_BloodSprite( const vec3_t org, int colorIndex, int modelIndex, int model
pTemp->entity.curstate.rendercolor.g = clgame.palette[colorIndex][1];
pTemp->entity.curstate.rendercolor.b = clgame.palette[colorIndex][2];
pTemp->entity.curstate.framerate = frameCount * 4; // Finish in 0.250 seconds
pTemp->die = cl.time + Com_RandomFloat( 3.0f, 6.0f );
pTemp->die = cl.time + Com_RandomFloat( 1.0f, 3.0f );
pTemp->entity.angles[2] = Com_RandomLong( 0, 360 );
pTemp->bounceFactor = 0;
@ -1065,9 +1064,6 @@ void CL_Sprite_Explode( TEMPENTITY *pTemp, float scale, int flags )
{
if( !pTemp ) return;
// NOTE: Xash3D doesn't needs this stuff, because sprites
// have right rendermodes already at loading point
// but i'm leave it for backward compatibility
if( flags & TE_EXPLFLAG_NOADDITIVE )
{
// solid sprite
@ -1076,7 +1072,7 @@ void CL_Sprite_Explode( TEMPENTITY *pTemp, float scale, int flags )
}
else if( flags & TE_EXPLFLAG_DRAWALPHA )
{
// alpha sprite
// alpha sprite (came from hl2)
pTemp->entity.curstate.rendermode = kRenderTransAlpha;
pTemp->entity.curstate.renderamt = 180;
}
@ -1089,6 +1085,7 @@ void CL_Sprite_Explode( TEMPENTITY *pTemp, float scale, int flags )
if( flags & TE_EXPLFLAG_ROTATE )
{
// came from hl2
pTemp->entity.angles[2] = Com_RandomLong( 0, 360 );
}
@ -1213,7 +1210,7 @@ void CL_Sprite_Trail( int type, const vec3_t vecStart, const vec3_t vecEnd, int
VectorSubtract( vecEnd, vecStart, vecDelta );
VectorNormalize2( vecDelta, vecDir );
flAmplitude /= 256.0;
flAmplitude /= 256.0f;
for( i = 0; i < nCount; i++ )
{
@ -1226,7 +1223,7 @@ void CL_Sprite_Trail( int type, const vec3_t vecStart, const vec3_t vecEnd, int
pTemp = CL_TempEntAlloc( vecPos, Mod_Handle( modelIndex ));
if( !pTemp ) return;
pTemp->flags |= FTENT_COLLIDEWORLD | FTENT_SPRCYCLE | FTENT_FADEOUT | FTENT_SLOWGRAVITY;
pTemp->flags = (FTENT_COLLIDEWORLD|FTENT_SPRCYCLE|FTENT_FADEOUT|FTENT_SLOWGRAVITY);
VectorScale( vecDir, flSpeed, vecVel );
vecVel[0] += Com_RandomFloat( -127.0f, 128.0f ) * flAmplitude;
@ -1250,12 +1247,12 @@ void CL_Sprite_Trail( int type, const vec3_t vecStart, const vec3_t vecEnd, int
===============
CL_Large_Funnel
Create a funnel effect
Create a funnel effect (particles only)
===============
*/
void CL_Large_Funnel( const vec3_t pos, int flags )
{
CL_FunnelSprite( pos, CL_FindModelIndex( "sprites/flare6.spr" ), flags );
CL_FunnelSprite( pos, 0, flags );
}
/*
@ -1280,7 +1277,7 @@ void CL_FunnelSprite( const vec3_t pos, int spriteIndex, int flags )
{
for( j = -256; j <= 256; j += 32 )
{
if( pTemp )
if( pTemp || !spriteIndex )
{
pPart = CL_AllocParticle( NULL );
pTemp = NULL;
@ -1304,7 +1301,8 @@ void CL_FunnelSprite( const vec3_t pos, int spriteIndex, int flags )
// send particle heading to dest at a random speed
VectorSubtract( dest, m_vecPos, dir );
vel = dest[2] / 8;// velocity based on how far particle has to travel away from org
// velocity based on how far particle has to travel away from org
vel = dest[2] / 8;
}
else
{
@ -1315,7 +1313,8 @@ void CL_FunnelSprite( const vec3_t pos, int spriteIndex, int flags )
// send particle heading to org at a random speed
VectorSubtract( pos, m_vecPos, dir );
vel = m_vecPos[2] / 8;// velocity based on how far particle starts from org
// velocity based on how far particle starts from org
vel = m_vecPos[2] / 8;
}
flDist = VectorNormalizeLength( dir ); // save the distance
@ -1541,7 +1540,7 @@ void CL_Explosion( vec3_t pos, int model, float scale, float framerate, int flag
dl->radius = 200;
dl->color.r = dl->color.g = 250;
dl->color.b = 150;
dl->die = cl.time + 0.01f;
dl->die = cl.time + 0.25f;
dl->decay = 800;
// red glow
@ -1565,6 +1564,60 @@ void CL_Explosion( vec3_t pos, int model, float scale, float framerate, int flag
S_StartSound( pos, 0, CHAN_AUTO, hSound, VOL_NORM, ATTN_NORM, PITCH_NORM, 0 );
}
/*
==============
CL_PlayerSprites
Create a particle smoke around player
==============
*/
void CL_PlayerSprites( int client, int modelIndex, int count, int size )
{
TEMPENTITY *pTemp;
cl_entity_t *pEnt;
float vel;
int i;
pEnt = CL_GetEntityByIndex( client );
if( !pEnt || !pEnt->player )
{
MsgDev( D_INFO, "Bad ent %i in R_PlayerSprites()!\n", client );
return;
}
vel = 128;
for( i = 0; i < count; i++ )
{
pTemp = CL_DefaultSprite( pEnt->origin, modelIndex, 15 );
if( !pTemp ) return;
pTemp->entity.curstate.rendermode = kRenderTransAlpha;
pTemp->entity.curstate.renderfx = kRenderFxNone;
pTemp->entity.baseline.origin[0] = Com_RandomFloat( -1.0f, 1.0f ) * vel;
pTemp->entity.baseline.origin[1] = Com_RandomFloat( -1.0f, 1.0f ) * vel;
pTemp->entity.baseline.origin[2] = Com_RandomFloat( 0.0f, 1.0f ) * vel;
pTemp->entity.curstate.rendercolor.r = 192;
pTemp->entity.curstate.rendercolor.g = 192;
pTemp->entity.curstate.rendercolor.b = 192;
pTemp->entity.curstate.renderamt = 64;
pTemp->entity.curstate.scale = size;
}
}
/*
==============
CL_Sprite_WallPuff
Create a wallpuff
==============
*/
void CL_Sprite_WallPuff( TEMPENTITY *pTemp, float scale )
{
// TODO: implement
}
/*
==============
CL_MultiGunshot
@ -1589,39 +1642,6 @@ void CL_FireField( float *org, int radius, int modelIndex, int count, int flags,
// TODO: implement
}
/*
==============
CL_Sprite_WallPuff
Create a wallpuff
==============
*/
void CL_Sprite_WallPuff( TEMPENTITY *pTemp, float scale )
{
// TODO: implement
}
/*
==============
CL_PlayerSprites
Unknown effect
==============
*/
void CL_PlayerSprites( int client, int modelIndex, int count, int size )
{
#if 0
// TODO: implement
MESSAGE_BEGIN( MSG_ONE, SVC_TEMPENTITY, g_vecZero, pev );
WRITE_BYTE( TE_PLAYERSPRITES );
WRITE_SHORT( ENTINDEX( ENT( pev ) ) );
WRITE_SHORT( g_sModelIndexFire );
WRITE_BYTE( 20 );
WRITE_BYTE( 10 );
MESSAGE_END( );
#endif
}
/*
==============
CL_ParseTempEntity
@ -2036,7 +2056,7 @@ void CL_ParseTempEntity( sizebuf_t *msg )
CL_Projectile( pos, pos2, modelIndex, life, color, NULL );
break;
case TE_PLAYERSPRITES:
color = BF_ReadByte( &buf ); // playernum
color = BF_ReadShort( &buf ); // entitynum
modelIndex = BF_ReadShort( &buf );
count = BF_ReadByte( &buf );
random = (float)BF_ReadByte( &buf );
@ -2100,12 +2120,12 @@ void CL_ParseTempEntity( sizebuf_t *msg )
CL_UserTracerParticle( pos, pos2, life, color, scale, 0, NULL );
break;
default:
MsgDev( D_ERROR, "ParseTempEntity: illegible te_message %i\n", type );
MsgDev( D_ERROR, "ParseTempEntity: illegible TE message %i\n", type );
break;
}
// throw warning
if( BF_CheckOverflow( &buf )) MsgDev( D_WARN, "ParseTempEntity: overflow te_message\n" );
if( BF_CheckOverflow( &buf )) MsgDev( D_WARN, "ParseTempEntity: overflow TE message\n" );
}
@ -2116,7 +2136,7 @@ LIGHT STYLE MANAGEMENT
==============================================================
*/
#define STYLE_LERPING_THRESHOLD 3.0f // because we wan't interpolate fast sequences (e.g. on\off)
#define STYLE_LERPING_THRESHOLD 3.0f // because we wan't interpolate fast sequences (like on\off)
/*
================
@ -2213,7 +2233,7 @@ dlight_t *CL_AllocDlight( int key )
// then look for anything else
for( i = 0, dl = cl_dlights; i < MAX_DLIGHTS; i++, dl++ )
{
if( dl->die < cl.time )
if( dl->die < cl.time && dl->key == 0 )
{
Q_memset( dl, 0, sizeof( *dl ));
dl->key = key;
@ -2258,7 +2278,7 @@ dlight_t *CL_AllocElight( int key )
// then look for anything else
for( i = 0, dl = cl_elights; i < MAX_ELIGHTS; i++, dl++ )
{
if( dl->die < cl.time )
if( dl->die < cl.time && dl->key == 0 )
{
Q_memset( dl, 0, sizeof( *dl ));
dl->key = key;

View File

@ -29,7 +29,7 @@ void SCR_RebuildGammaTable( void )
g = bound( 0.5f, vid_gamma->value, 2.3f );
// screenshots gamma
// movie gamma
for( i = 0; i < 256; i++ )
{
if( g == 1 ) clgame.ds.gammaTable[i] = i;
@ -207,7 +207,7 @@ qboolean SCR_PlayCinematic( const char *arg )
if( FS_FileExists( arg, false ) && !fullpath )
{
MsgDev( D_ERROR, "couldn't load %s from packfile. Please extract it\n", path );
MsgDev( D_ERROR, "Couldn't load %s from packfile. Please extract it\n", path );
return false;
}
@ -245,7 +245,7 @@ long SCR_GetAudioChunk( char *rawdata, long length )
int r;
r = AVI_GetAudioChunk( cin_state, rawdata, cin_audio.loopStart, length );
cin_audio.loopStart += r; // advance play position
cin_audio.loopStart += r; // advance play position
return r;
}

View File

@ -10,18 +10,6 @@
#include "gl_local.h"
#include "vgui_draw.h"
/*
====================
V_ClearScene
Specifies the model that will be used as the world
====================
*/
void V_ClearScene( void )
{
R_ClearScene();
}
/*
===============
V_SetupRefDef
@ -68,19 +56,11 @@ void V_SetupRefDef( void )
cl.refdef.fov_x = cl.data.fov; // this is a final fov value
cl.refdef.fov_y = V_CalcFov( &cl.refdef.fov_x, cl.refdef.viewport[2], cl.refdef.viewport[3] );
// calculate the origin
if( CL_IsPredicted( ) && !cl.refdef.demoplayback )
{
// use predicted values
float backlerp = 1.0f - cl.lerpFrac;
int i;
for( i = 0; i < 3; i++ )
{
cl.refdef.simorg[i] = cl.predicted_origin[i] - backlerp * cl.prediction_error[i];
cl.refdef.viewheight[i] = cl.predicted_viewofs[i] - backlerp * cl.prediction_error[i];
}
VectorCopy( cl.predicted_origin, cl.refdef.simorg );
VectorCopy( cl.predicted_velocity, cl.refdef.simvel );
VectorCopy( cl.predicted_viewofs, cl.refdef.viewheight );
}
else
{
@ -124,7 +104,7 @@ void V_RenderView( void )
{
cl.force_refdef = false;
V_ClearScene ();
R_ClearScene ();
CL_AddEntities ();
V_SetupRefDef ();
}
@ -153,7 +133,7 @@ qboolean V_PreRender( void )
// if the screen is disabled (loading plaque is up)
if( cls.disable_screen )
{
if(( host.realtime - cls.disable_screen ) > 60.0f )
if(( host.realtime - cls.disable_screen ) > cl_timeout->value )
{
MsgDev( D_NOTE, "V_PreRender: loading plaque timed out.\n" );
cls.disable_screen = 0.0f;
@ -182,7 +162,7 @@ void V_PostRender( void )
VGui_Paint();
}
if( cls.scrshot_action == scrshot_inactive )
if( cls.scrshot_action == scrshot_inactive || cls.scrshot_action == scrshot_normal )
{
SCR_RSpeeds();
SCR_NetSpeeds();

View File

@ -106,12 +106,9 @@ typedef struct
event_state_t events;
// predicting stuff
vec3_t predicted_origins[CMD_BACKUP]; // for debug comparing against server
vec3_t predicted_origin; // generated by CL_PredictMovement
vec3_t predicted_origin; // generated by CL_PredictMovement
vec3_t predicted_viewofs;
vec3_t predicted_angles;
vec3_t predicted_velocity;
vec3_t prediction_error;
// server state information
int playernum;
@ -467,9 +464,9 @@ extern convar_t *cl_predict;
extern convar_t *cl_smooth;
extern convar_t *cl_showfps;
extern convar_t *cl_envshot_size;
extern convar_t *cl_timeout;
extern convar_t *cl_nodelta;
extern convar_t *cl_crosshair;
extern convar_t *cl_showmiss;
extern convar_t *cl_testlights;
extern convar_t *cl_solid_players;
extern convar_t *cl_idealpitchscale;
@ -595,7 +592,6 @@ void SCR_DrawFPS( void );
void V_Init (void);
void V_Shutdown( void );
void V_ClearScene( void );
qboolean V_PreRender( void );
void V_PostRender( void );
void V_RenderView( void );

View File

@ -47,17 +47,25 @@ void GL_BackendEndFrame( void )
switch( r_speeds->integer )
{
case 5:
case 1:
Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i wpoly, %3i bpoly\n%3i epoly, %3i spoly",
r_stats.c_world_polys, r_stats.c_brush_polys, r_stats.c_studio_polys, r_stats.c_sprite_polys );
break;
case 2:
Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "visible leafs:\n%3i leafs",
r_stats.c_world_leafs );
break;
case 3:
Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i studio models drawn\n%3i sprites drawn",
r_stats.c_studio_models_drawn, r_stats.c_sprite_models_drawn );
break;
case 6:
case 4:
Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i static entities\n%3i normal entities",
r_numStatics, r_numEntities );
break;
case 7:
Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i temp entities\n%3i view beams",
r_stats.c_active_tents_count, r_stats.c_view_beams_count );
case 5:
Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i tempents\n%3i viewbeams\n%3i particles",
r_stats.c_active_tents_count, r_stats.c_view_beams_count, r_stats.c_particle_count );
}
Q_memset( &r_stats, 0, sizeof( r_stats ));
@ -431,7 +439,7 @@ void VID_ImageAdjustGamma( byte *in, uint width, uint height )
for( i = 0; i < 256; i++ )
{
if ( g == 1.0f ) r_gammaTable[i] = i;
else r_gammaTable[i] = bound( 0, 255 * pow((i + 0.5)/255.5f, g ) + 0.5, 255 );
else r_gammaTable[i] = bound( 0, 255 * pow((i + 0.5) / 255.5f, g ) + 0.5f, 255 );
}
// adjust screenshots gamma

View File

@ -719,7 +719,7 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos
model_t *model = NULL;
int width, height;
if( textureIndex <= 0 || textureIndex > MAX_TEXTURES )
if( textureIndex <= 0 || textureIndex >= MAX_TEXTURES )
{
MsgDev( D_ERROR, "Decal has invalid texture!\n" );
return;
@ -731,17 +731,15 @@ void R_DecalShoot( int textureIndex, int entityIndex, int modelIndex, vec3_t pos
if( modelIndex > 0 ) model = Mod_Handle( modelIndex );
else if( ent != NULL ) model = Mod_Handle( ent->curstate.modelindex );
else
{
Msg( "ent = NULL, model = NULL on entity %i, model %i\n", entityIndex, modelIndex );
return;
}
else return;
}
else if( modelIndex > 0 )
model = Mod_Handle( modelIndex );
else model = cl.worldmodel;
if( !model || model->type != mod_brush )
if( !model ) return;
if( model->type != mod_brush )
{
MsgDev( D_ERROR, "Decals must hit mod_brush!\n" );
return;
@ -866,7 +864,7 @@ void DrawSurfaceDecals( msurface_t *fa )
pglEnable( GL_POLYGON_OFFSET_FILL );
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); // try to use GL_MODULATE ?
for( p = fa->pdecals; p; p = p->pnext )
DrawSingleDecal( p, fa );
@ -1032,7 +1030,7 @@ int R_CreateDecalList( decallist_t *pList, qboolean changelevel )
===============
R_DecalRemoveAll
remove all decals with specified shader
remove all decals with specified texture
===============
*/
void R_DecalRemoveAll( int textureIndex )
@ -1040,7 +1038,7 @@ void R_DecalRemoveAll( int textureIndex )
decal_t *pdecal;
int i;
if( !textureIndex <= 0 || textureIndex > MAX_TEXTURES )
if( textureIndex <= 0 || textureIndex >= MAX_TEXTURES )
{
MsgDev( D_ERROR, "Decal has invalid texture!\n" );
return;

View File

@ -32,7 +32,6 @@ void GL_Bind( GLenum tmu, GLenum texnum )
// missed texture ?
if( texnum <= 0 ) texnum = tr.defaultTexture;
ASSERT( texnum > 0 && texnum < MAX_TEXTURES );
GL_SelectTexture( tmu );
@ -59,7 +58,6 @@ void GL_MBind( GLenum texnum )
// missed texture ?
if( texnum <= 0 ) texnum = tr.defaultTexture;
ASSERT( texnum > 0 && texnum < MAX_TEXTURES );
if( glState.mtexEnabled )

View File

@ -198,6 +198,7 @@ typedef struct
uint c_active_tents_count;
uint c_studio_models_drawn;
uint c_sprite_models_drawn;
uint c_particle_count;
} ref_speeds_t;
extern ref_speeds_t r_stats;
@ -299,12 +300,8 @@ void R_DrawFog( void );
//
// gl_rmath.c
//
void R_InitMathlib( void );
void R_LatLongToNorm( const byte latlong[2], vec3_t normal );
void R_NormToLatLong( const vec3_t normal, byte latlong[2] );
float V_CalcFov( float *fov_x, float width, float height );
void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolean lock_x );
byte R_FloatToByte( float x );
void Matrix4x4_ToArrayFloatGL( const matrix4x4 in, float out[16] );
void Matrix4x4_FromArrayFloatGL( matrix4x4 out, const float in[16] );
void Matrix4x4_Concat( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );

View File

@ -273,12 +273,12 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
VectorCopy( point, end );
if( invLight )
{
start[2] = point[2] - 64;
start[2] = point[2] - 1;
end[2] = point[2] + 8192;
}
else
{
start[2] = point[2] + 64;
start[2] = point[2] + 1;
end[2] = point[2] - 8192;
}
@ -295,20 +295,41 @@ void R_LightForPoint( const vec3_t point, color24 *ambientLight, qboolean invLig
if( m_pGround && m_pGround->model )
{
matrix4x4 matrix;
hull_t *hull;
vec3_t start_l, end_l;
vec3_t offset;
pmodel = m_pGround->model;
pnodes = &pmodel->nodes[pmodel->hulls[0].firstclipnode];
hull = &pmodel->hulls[0];
VectorSubtract( hull->clip_mins, vec3_origin, offset );
VectorAdd( offset, m_pGround->origin, offset );
VectorSubtract( start, offset, start_l );
VectorSubtract( end, offset, end_l );
// rotate start and end into the models frame of reference
if( !VectorIsNull( m_pGround->angles ))
{
matrix4x4 imatrix;
Matrix4x4_CreateFromEntity( matrix, m_pGround->angles, offset, 1.0f );
Matrix4x4_Invert_Simple( imatrix, matrix );
Matrix4x4_VectorTransform( imatrix, start, start_l );
Matrix4x4_VectorTransform( imatrix, end, end_l );
}
// copy transformed pos back
VectorCopy( start_l, start );
VectorCopy( end_l, end );
}
if( RI.isSkyVisible )
{
r_pointColor[0] = RI.refdef.movevars->skycolor_r;
r_pointColor[1] = RI.refdef.movevars->skycolor_g;
r_pointColor[2] = RI.refdef.movevars->skycolor_b;
}
else
{
VectorClear( r_pointColor );
}
r_pointColor[0] = RI.refdef.movevars->skycolor_r;
r_pointColor[1] = RI.refdef.movevars->skycolor_g;
r_pointColor[2] = RI.refdef.movevars->skycolor_b;
if( R_RecursiveLightPoint( pmodel, pnodes, start, end ))
{

View File

@ -7,67 +7,6 @@
#include "gl_local.h"
#include "mathlib.h"
#define FTABLE_SIZE_POW 10
#define NOISE_SIZE 256
#define FTABLE_SIZE ( 1<<FTABLE_SIZE_POW )
#define NOISE_VAL( a ) r_noiseperm[( a ) & ( NOISE_SIZE - 1 )]
#define FTABLE_CLAMP( x ) (((uint)( ( x )*FTABLE_SIZE ) & ( FTABLE_SIZE-1 )))
#define FTABLE_EVALUATE( table, x ) (( table )[FTABLE_CLAMP( x )] )
#define NOISE_INDEX( x, y, z, t ) NOISE_VAL( x + NOISE_VAL( y + NOISE_VAL( z + NOISE_VAL( t ) ) ) )
#define NOISE_LERP( a, b, w ) ( a * ( 1.0f - w ) + b * w )
static float r_sintableByte[256];
static float r_sintable[FTABLE_SIZE];
static float r_triangletable[FTABLE_SIZE];
static float r_squaretable[FTABLE_SIZE];
static float r_sawtoothtable[FTABLE_SIZE];
static float r_inversesawtoothtable[FTABLE_SIZE];
static float r_noisetable[NOISE_SIZE];
static int r_noiseperm[NOISE_SIZE];
static float r_warpsintable[256] =
{
#include "warpsin.h"
};
/*
==============
R_InitMathlib
==============
*/
void R_InitMathlib( void )
{
int i;
float t;
// build lookup tables
for( i = 0; i < FTABLE_SIZE; i++ )
{
t = (float)i / (float)FTABLE_SIZE;
r_sintable[i] = sin( t * M_PI2 );
if( t < 0.25f ) r_triangletable[i] = t * 4.0f;
else if( t < 0.75f ) r_triangletable[i] = 2.0f - 4.0f * t;
else r_triangletable[i] = ( t - 0.75f ) * 4.0f - 1.0f;
if( t < 0.5f ) r_squaretable[i] = 1.0f;
else r_squaretable[i] = -1.0f;
r_sawtoothtable[i] = t;
r_inversesawtoothtable[i] = 1.0f - t;
}
for( i = 0; i < 256; i++ )
r_sintableByte[i] = sin((float)i / 255.0f * M_PI2 );
// init the noise table
for( i = 0; i < NOISE_SIZE; i++ )
{
r_noisetable[i] = Com_RandomFloat( -1.0f, 1.0f );
r_noiseperm[i] = Com_RandomLong( 0, 255 );
}
}
/*
====================
V_CalcFov
@ -118,70 +57,6 @@ void V_AdjustFov( float *fov_x, float *fov_y, float width, float height, qboolea
else *fov_y = y;
}
/*
=============
R_NormToLatLong
=============
*/
void R_NormToLatLong( const vec3_t normal, byte latlong[2] )
{
// can't do atan2 (normal[1], normal[0])
if( normal[0] == 0 && normal[1] == 0 )
{
if( normal[2] > 0 )
{
latlong[0] = 0; // acos ( 1 )
latlong[1] = 0;
}
else
{
latlong[0] = 128; // acos ( -1 )
latlong[1] = 0;
}
}
else
{
int angle;
angle = (int)(acos( normal[2]) * 255.0 / M_PI2 ) & 255;
latlong[0] = angle;
angle = (int)(atan2( normal[1], normal[0] ) * 255.0 / M_PI2 ) & 255;
latlong[1] = angle;
}
}
/*
=============
R_LatLongToNorm
=============
*/
void R_LatLongToNorm( const byte latlong[2], vec3_t normal )
{
float sin_a, sin_b, cos_a, cos_b;
cos_a = r_sintableByte[(latlong[0] + 64) & 255];
sin_a = r_sintableByte[latlong[0]];
cos_b = r_sintableByte[(latlong[1] + 64) & 255];
sin_b = r_sintableByte[latlong[1]];
VectorSet( normal, cos_b * sin_a, sin_b * sin_a, cos_a );
}
byte R_FloatToByte( float x )
{
union {
float f;
uint i;
} f2i;
// shift float to have 8bit fraction at base of number
f2i.f = x + 32768.0f;
f2i.i &= 0x7FFFFF;
// then read as integer and kill float bits...
return ( byte )min( f2i.i, 255 );
}
/*
========================================================================

View File

@ -446,6 +446,8 @@ void CL_UpdateParticle( particle_t *p, float ft )
pglEnd();
r_stats.c_particle_count++;
if( p->type != pt_clientcustom )
{
// update position.

View File

@ -645,7 +645,9 @@ void R_RenderBrushPoly( msurface_t *fa )
{
texture_t *t;
r_stats.c_brush_polys++;
if( RI.currententity == clgame.entities )
r_stats.c_world_polys++;
else r_stats.c_brush_polys++;
if( fa->flags & SURF_DRAWSKY )
{
@ -759,6 +761,10 @@ void R_DrawTextureChains( void )
pglColor4ub( 255, 255, 255, 255 );
R_LoadIdentity(); // set identity matrix
// restore worldmodel
RI.currententity = clgame.entities;
RI.currentmodel = RI.currententity->model;
// clip skybox surfaces
for( s = skychain; s != NULL; s = s->texturechain )
R_AddSkyBoxSurface( s );
@ -1160,7 +1166,6 @@ void R_DrawStaticBrushes( void )
=============================================================
*/
/*
================
R_RecursiveWorldNode

View File

@ -786,6 +786,8 @@ static void R_DrawSpriteQuad( mspriteframe_t *frame, vec3_t org, vec3_t v_right,
{
vec3_t point;
r_stats.c_sprite_polys++;
pglBegin( GL_QUADS );
pglTexCoord2f( 0.0f, 1.0f );
VectorMA( org, frame->down * scale, v_up, point );

View File

@ -1715,6 +1715,8 @@ static void R_StudioDrawPoints( void )
pglBegin( GL_TRIANGLE_STRIP );
}
r_stats.c_studio_polys++;
for( ; i > 0; i--, ptricmds += 4 )
{
if( flags & STUDIO_NF_CHROME || ( g_nFaceFlags & STUDIO_NF_CHROME ))

View File

@ -1434,6 +1434,9 @@ void GL_InitCommands( void )
gl_finish = Cvar_Get( "gl_finish", "0", CVAR_ARCHIVE, "use glFinish instead of glFlush" );
gl_clear = Cvar_Get( "gl_clear", "0", CVAR_ARCHIVE, "clearing screen after each frame" );
gl_test = Cvar_Get( "gl_test", "0", 0, "engine developer cvar for quick testing new features" );
// these cvar not used by engine but some mods requires this
Cvar_Get( "gl_polyoffset", "-0.1", 0, "polygon offset for decals" );
// make sure r_swapinterval is checked after vid_restart
gl_swapInterval->modified = true;
@ -1639,7 +1642,6 @@ qboolean R_Init( void )
GL_InitExtensions();
GL_SetDefaults();
R_InitMathlib();
R_InitImages();
R_SpriteInit();
R_StudioInit();

View File

@ -355,7 +355,7 @@ cvar_t *pfnCVarGetPointer( const char *szVarName )
cvPtr = (cvar_t *)Cvar_FindVar( szVarName );
Msg( "GetCVarPointer: %s - %s\n", szVarName, cvPtr != NULL ? "done" : "fail" );
Msg( "GetCVarPointer: %s - %s\n", szVarName, cvPtr != NULL ? "^2done" : "^1fail" );
return cvPtr;
}

View File

@ -154,10 +154,6 @@ SOURCE=.\client\cl_pmove.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_pred.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_scrn.c
# End Source File
# Begin Source File