/* ================= CL_CreateCmd ================= */ void CL_CreateCmd( void ) { usercmd_t cmd = { 0 }; color24 color; vec3_t angles; qboolean active; int ms; ms = host.frametime * 1000; if( ms > 250 ) ms = 100; // time was unreasonable else if( ms <= 0 ) ms = 1; // keep time an actual // build list of all solid entities per next frame (exclude clients) CL_SetSolidEntities (); CL_SetSolidPlayers ( cl.playernum ); VectorCopy( cl.refdef.cl_viewangles, angles ); VectorCopy( cl.frame.local.client.origin, cl.data.origin ); VectorCopy( cl.refdef.cl_viewangles, cl.data.viewangles ); cl.data.iWeaponBits = cl.frame.local.client.weapons; if( cl.scr_fov < 1.0f || cl.scr_fov> 170.0f ) cl.scr_fov = 90.0f; cl.data.fov = cl.scr_fov; clgame.dllFuncs.pfnUpdateClientData( &cl.data, cl.time ); // grab changes VectorCopy( cl.data.viewangles, cl.refdef.cl_viewangles ); cl.frame.local.client.weapons = cl.data.iWeaponBits; cl.scr_fov = cl.data.fov; if( cl.scr_fov < 1.0f || cl.scr_fov> 170.0f ) cl.scr_fov = 90.0f; // allways dump the first ten messages, // because it may contain leftover inputs // from the last level if( ++cl.movemessages <= 10 ) { if( !cls.demoplayback ) { cl.refdef.cmd = &cl.cmds[cls.netchan.outgoing_sequence & CL_UPDATE_MASK]; *cl.refdef.cmd = cmd; } return; } active = ( cls.state == ca_active && !cl.refdef.paused && !cls.demoplayback ); clgame.dllFuncs.CL_CreateMove( cl.time - cl.oldtime, &cmd, active ); // after command generated in client, // add motion events from engine controls IN_EngineAppendMove( host.frametime, &cmd, active); R_LightForPoint( cl.frame.local.client.origin, &color, false, false, 128.0f ); cmd.lightlevel = (color.r + color.g + color.b) / 3; // never let client.dll calc frametime for player // because is potential backdoor for cheating cmd.msec = ms; cmd.lerp_msec = cl_interp->value * 1000; cmd.lerp_msec = bound( 0, cmd.lerp_msec, 250 ); V_ProcessOverviewCmds( &cmd ); V_ProcessShowTexturesCmds( &cmd ); if(( cl.background && !cls.demoplayback ) || gl_overview->integer || cls.changelevel ) { VectorCopy( angles, cl.refdef.cl_viewangles ); VectorCopy( angles, cmd.viewangles ); cmd.msec = 0; } // demo always have commands // so don't overwrite them if( !cls.demoplayback ) { int frame = cls.netchan.outgoing_sequence & CL_UPDATE_MASK; cl.refdef.cmd = &cl.cmds[frame]; *cl.refdef.cmd = cmd; cl.runfuncs[frame] = TRUE; } }
void CParticleSystem :: DrawParticle( CParticle *part, Vector &right, Vector &up ) { float fSize = part->m_fSize; // nothing to draw? if( fSize <= 0 ) return; // frustrum visible check if( !ParticleIsVisible( part )) return; Vector point1, point2, point3, point4; Vector origin = part->origin; float fCosSize = CosLookup( part->m_fAngle ) * fSize; float fSinSize = SinLookup( part->m_fAngle ) * fSize; // calculate the four corners of the sprite point1 = origin + up * fSinSize + right * -fCosSize; point2 = origin + up * fCosSize + right * fSinSize; point3 = origin + up * -fSinSize + right * fCosSize; point4 = origin + up * -fCosSize + right * -fSinSize; int iContents = CONTENTS_NONE; model_t *pModel; for( CParticle *pDraw = part; pDraw; pDraw = pDraw->m_pOverlay ) { if( !pDraw->pType->m_hSprite ) continue; if( pDraw->pType->m_iDrawCond ) { if( pDraw->pType->m_iDrawCond == CONTENT_SPOTLIGHT ) { if( !R_CountPlights( )) continue; // fast reject for( int i = 0; i < MAX_PLIGHTS; i++ ) { plight_t *pl = &cl_plights[i]; if( pl->die < GET_CLIENT_TIME() || !pl->radius ) continue; if( !R_CullSphereExt( pl->frustum, part->origin, part->m_fSize + 1, pl->clipflags )) break; // cone intersected with particle } if( i == MAX_PLIGHTS ) continue; // no intersection } else { if( iContents == CONTENTS_NONE ) iContents = POINT_CONTENTS( origin ); if( iContents != pDraw->pType->m_iDrawCond ) continue; } } pModel = (model_t *)gEngfuncs.GetSpritePointer( pDraw->pType->m_hSprite ); // if we've reached the end of the sprite's frames, loop back while (pDraw->frame > pModel->numframes) pDraw->frame -= pModel->numframes; while (pDraw->frame < 0) pDraw->frame += pModel->numframes; if( !TriSpriteTexture( pModel, (int)pDraw->frame )) continue; gEngfuncs.pTriAPI->RenderMode( pDraw->pType->m_iRenderMode ); if( m_iLightingModel >= 1 ) { color24 lightColor; Vector lightingColor; if( m_iLightingModel == 1 ) R_LightForPoint( part->origin, &lightColor, false, true, fSize + 1 ); else R_LightForPoint( part->origin, &lightColor, false, true, 0.0f ); // FIXME: this code is totally wrong. // We need a fake lightmap here like in sprite implementation lightingColor.x = pDraw->m_fRed * lightColor.r * (1.0f / 255.0f); lightingColor.y = pDraw->m_fGreen * lightColor.g * (1.0f / 255.0f); lightingColor.z = pDraw->m_fBlue * lightColor.b * (1.0f / 255.0f); pglColor4f( lightingColor.x, lightingColor.y, lightingColor.z, pDraw->m_fAlpha ); } else pglColor4f( pDraw->m_fRed, pDraw->m_fGreen, pDraw->m_fBlue, pDraw->m_fAlpha ); pglBegin( GL_QUADS ); pglTexCoord2f( 0.0f, 0.0f ); pglVertex3fv( point1 ); pglTexCoord2f( 1.0f, 0.0f ); pglVertex3fv( point2 ); pglTexCoord2f( 1.0f, 1.0f ); pglVertex3fv( point3 ); pglTexCoord2f( 0.0f, 1.0f ); pglVertex3fv( point4 ); pglEnd(); if( m_iLightingModel >=2 && R_CountPlights( )) { for( int i = 0; i < MAX_PLIGHTS; i++ ) { plight_t *pl = &cl_plights[i]; if( pl->die < GET_CLIENT_TIME() || !pl->radius ) continue; if( R_CullSphereExt( pl->frustum, part->origin, part->m_fSize + 1, pl->clipflags )) continue; R_BeginDrawProjection( pl ); pglBegin( GL_QUADS ); pglVertex3fv( point1 ); pglVertex3fv( point2 ); pglVertex3fv( point3 ); pglVertex3fv( point4 ); pglEnd(); R_EndDrawProjection(); } } } }