/* ================= CG_DrawActiveFrame Generates and draws a game scene and status information at the given time. ================= */ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback ) { int inwater; int mpSetup; // NERVE - SMF #ifdef DEBUGTIME_ENABLED int dbgTime=trap_Milliseconds(),elapsed; int dbgCnt=0; #endif cg.time = serverTime; cg.demoPlayback = demoPlayback; // update cvars CG_UpdateCvars(); #ifdef DEBUGTIME_ENABLED CG_Printf("\n"); #endif DEBUGTIME // if we are only updating the screen as a loading // pacifier, don't even try to read snapshots if ( cg.infoScreenText[0] != 0 ) { CG_DrawInformation(); return; } // any looped sounds will be respecified as entities // are added to the render list trap_S_ClearLoopingSounds(qfalse); DEBUGTIME // clear all the render lists trap_R_ClearScene(); DEBUGTIME // set up cg.snap and possibly cg.nextSnap CG_ProcessSnapshots(); DEBUGTIME // if we haven't received any snapshots yet, all // we can draw is the information screen if ( !cg.snap || ( cg.snap->snapFlags & SNAPFLAG_NOT_ACTIVE ) ) { CG_DrawInformation(); return; } // check for server set weapons we might not know about // (FIXME: this is a hack for the time being since a scripted "selectweapon" does // not hit the first snap, the server weapon set in cg_playerstate.c line 219 doesn't // do the trick) if( !cg.weaponSelect && cg.snap->ps.weapon) { cg.weaponSelect = cg.snap->ps.weapon; cg.weaponSelectTime = cg.time; } //----(SA) nerve uses this for snooper/sniper if (cg.weaponSelect == WP_FG42SCOPE) { float spd; spd = VectorLength(cg.snap->ps.velocity); if (spd > 180.0f) CG_FinishWeaponChange(WP_FG42SCOPE, WP_FG42); } DEBUGTIME if(!cg.lightstylesInited) CG_SetupDlightstyles(); DEBUGTIME // if we have been told not to render, don't if (cg_norender.integer) { return; } // this counter will be bumped for every valid scene we generate cg.clientFrame++; // update cg.predictedPlayerState CG_PredictPlayerState(); DEBUGTIME // decide on third person view cg.renderingThirdPerson = cg_thirdPerson.integer || (cg.snap->ps.stats[STAT_HEALTH] <= 0); // build cg.refdef inwater = CG_CalcViewValues(); DEBUGTIME // RF, draw the skyboxportal CG_DrawSkyBoxPortal(); DEBUGTIME if(inwater) CG_UnderwaterSounds(); DEBUGTIME // first person blend blobs, done after AnglesToAxis if ( !cg.renderingThirdPerson ) { CG_DamageBlendBlob(); } DEBUGTIME // build the render lists if ( !cg.hyperspace ) { CG_AddPacketEntities(); // adter calcViewValues, so predicted player state is correct CG_AddMarks(); DEBUGTIME // Rafael particles CG_AddParticles (); // done. DEBUGTIME CG_AddLocalEntities(); DEBUGTIME }
/* ================= CG_DrawActiveFrame Generates and draws a game scene and status information at the given time. ================= */ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback ) { int inwater; cg.cld = 0; // NERVE - SMF - reset clientDamage #ifdef DEBUGTIME_ENABLED int dbgTime = trap_Milliseconds(),elapsed; int dbgCnt = 0; #endif cg.time = serverTime; cg.demoPlayback = demoPlayback; // update cvars CG_UpdateCvars(); /* // RF, if we should force a weapon, then do so if( !cg.weaponSelect ) { if (cg_loadWeaponSelect.integer > 0) { cg.weaponSelect = cg_loadWeaponSelect.integer; cg.weaponSelectTime = cg.time; trap_Cvar_Set( "cg_loadWeaponSelect", "0" ); // turn it off } } */ #ifdef DEBUGTIME_ENABLED CG_Printf( "\n" ); #endif DEBUGTIME // if we are only updating the screen as a loading // pacifier, don't even try to read snapshots if ( cg.infoScreenText[0] != 0 ) { CG_DrawInformation(); return; } // any looped sounds will be respecified as entities // are added to the render list trap_S_ClearLoopingSounds( qfalse ); DEBUGTIME // clear all the render lists trap_R_ClearScene(); DEBUGTIME // set up cg.snap and possibly cg.nextSnap CG_ProcessSnapshots(); DEBUGTIME // if we haven't received any snapshots yet, all // we can draw is the information screen if ( !cg.snap || ( cg.snap->snapFlags & SNAPFLAG_NOT_ACTIVE ) ) { CG_DrawInformation(); return; } if ( cg.weaponSelect == WP_FG42SCOPE || cg.weaponSelect == WP_SNOOPERSCOPE || cg.weaponSelect == WP_SNIPERRIFLE ) { float spd; spd = VectorLength( cg.snap->ps.velocity ); if ( spd > 180.0f ) { switch ( cg.weaponSelect ) { case WP_FG42SCOPE: CG_FinishWeaponChange( cg.weaponSelect, WP_FG42 ); break; case WP_SNOOPERSCOPE: CG_FinishWeaponChange( cg.weaponSelect, WP_GARAND ); break; case WP_SNIPERRIFLE: CG_FinishWeaponChange( cg.weaponSelect, WP_MAUSER ); break; } } } DEBUGTIME if ( !cg.lightstylesInited ) { CG_SetupDlightstyles(); } DEBUGTIME // if we have been told not to render, don't if ( cg_norender.integer ) { return; } // this counter will be bumped for every valid scene we generate cg.clientFrame++; // update cg.predictedPlayerState CG_PredictPlayerState(); DEBUGTIME // decide on third person view cg.renderingThirdPerson = cg_thirdPerson.integer /*|| (cg.snap->ps.stats[STAT_HEALTH] <= 0)*/; // build cg.refdef inwater = CG_CalcViewValues(); CG_CalcShakeCamera(); CG_ApplyShakeCamera(); DEBUGTIME // RF, draw the skyboxportal CG_DrawSkyBoxPortal(); DEBUGTIME if ( inwater ) { CG_UnderwaterSounds(); } DEBUGTIME // first person blend blobs, done after AnglesToAxis if ( !cg.renderingThirdPerson ) { CG_DamageBlendBlob(); } DEBUGTIME // build the render lists if ( !cg.hyperspace ) { CG_AddPacketEntities(); // adter calcViewValues, so predicted player state is correct CG_AddMarks(); DEBUGTIME // Rafael particles CG_AddParticles(); // done. DEBUGTIME CG_AddLocalEntities(); DEBUGTIME }
/* ================= CG_DrawActiveFrame Generates and draws a game scene and status information at the given time. ================= */ void CG_DrawActiveFrame( int serverTime, stereoFrame_t stereoView, qboolean demoPlayback ) { int inwater; qboolean renderPlayerViewport[MAX_SPLITVIEW]; int i; cg.time = serverTime; cg.demoPlayback = demoPlayback; // if we are only updating the screen as a loading // pacifier, don't even try to read snapshots if ( cg.infoScreenText[0] != 0 ) { CG_DrawInformation(); return; } // any looped sounds will be respecified as entities // are added to the render list trap_S_ClearLoopingSounds(qfalse); // clear all the render lists trap_R_ClearScene(); // clear poly buffers for this frame CG_PB_ClearPolyBuffers(); // set up cg.snap and possibly cg.nextSnap CG_ProcessSnapshots( qfalse ); // if we haven't received any snapshots yet, all // we can draw is the information screen if ( !cg.snap || ( cg.snap->snapFlags & SNAPFLAG_NOT_ACTIVE ) ) { CG_DrawInformation(); return; } if ( !cg.lightstylesInited ) { CG_SetupDlightstyles(); } // this counter will be bumped for every valid scene we generate cg.clientFrame++; // Use single camera/viewport at intermission for (i = 0; i < CG_MaxSplitView(); i++) { if ( cg.localPlayers[i].playerNum != -1 && cg.snap->pss[i].pm_type != PM_INTERMISSION ) { // player present and not at intermission, keep viewports separate. break; } } cg.singleCamera = ( CG_NumLocalPlayers() > 1 && i == CG_MaxSplitView() ); cg.numViewports = 0; for (i = 0; i < CG_MaxSplitView(); i++) { if ( cg.localPlayers[i].playerNum == -1 ) { renderPlayerViewport[i] = qfalse; continue; } cg.cur_localPlayerNum = i; cg.cur_lc = &cg.localPlayers[i]; cg.cur_ps = &cg.snap->pss[i]; // Check if viewport should be drawn. if ( cg.singleCamera && cg.numViewports >= 1 ) { renderPlayerViewport[i] = qfalse; } else { cg.numViewports++; renderPlayerViewport[i] = qtrue; } // update cg.predictedPlayerState CG_PredictPlayerState(); // Remove expired console lines if( cg.cur_lc->consoleLines[ 0 ].time + cg_consoleLatency.integer < cg.time && cg_consoleLatency.integer > 0 ) { CG_RemoveNotifyLine( cg.cur_lc ); } } cg.cur_localPlayerNum = -1; cg.cur_lc = NULL; cg.cur_ps = NULL; // If all local players dropped out from playing still draw main local player. if (cg.numViewports == 0) { cg.numViewports = 1; renderPlayerViewport[0] = qtrue; } // play lead change annoucement and time/frag limit warnings CG_CheckGameSounds(); // add buffered sounds CG_PlayBufferedSounds(); #ifdef MISSIONPACK // play buffered voice chats CG_PlayBufferedVoiceChats(); #endif for (i = 0, cg.viewport = -1; i < CG_MaxSplitView(); i++) { if (!renderPlayerViewport[i]) { continue; } cg.viewport++; cg.cur_localPlayerNum = i; cg.cur_lc = &cg.localPlayers[i]; cg.cur_ps = &cg.snap->pss[i]; // decide on third person view cg.cur_lc->renderingThirdPerson = cg.cur_ps->persistant[PERS_TEAM] != TEAM_SPECTATOR && (cg_thirdPerson[cg.cur_localPlayerNum].integer || (cg.cur_ps->stats[STAT_HEALTH] <= 0) || cg.cur_lc->cameraOrbit); // build cg.refdef inwater = CG_CalcViewValues(); CG_SetupFrustum(); CG_DrawSkyBoxPortal(); // first person blend blobs, done after AnglesToAxis if ( !cg.cur_lc->renderingThirdPerson ) { CG_DamageBlendBlob(); } // build the render lists if ( !cg.cur_lc->hyperspace ) { CG_AddPacketEntities(); // adter calcViewValues, so predicted player state is correct CG_AddMarks(); CG_AddParticles (); CG_AddLocalEntities(); CG_AddAtmosphericEffects(); } CG_AddViewWeapon( &cg.cur_lc->predictedPlayerState ); // finish up the rest of the refdef if ( cg.testModelEntity.hModel ) { CG_AddTestModel(); } cg.refdef.time = cg.time; memcpy( cg.refdef.areamask, cg.snap->areamask[i], sizeof( cg.refdef.areamask ) ); // warning sounds when powerup is wearing off CG_PowerupTimerSounds(); // update audio positions trap_S_Respatialize( cg.cur_ps->playerNum, cg.refdef.vieworg, cg.refdef.viewaxis, inwater, !cg.cur_lc->renderingThirdPerson ); // make sure the lagometerSample and frame timing isn't done twice when in stereo if ( stereoView != STEREO_RIGHT && cg.viewport == 0 ) { cg.frametime = cg.time - cg.oldTime; if ( cg.frametime < 0 ) { cg.frametime = 0; } cg.oldTime = cg.time; CG_AddLagometerFrameInfo(); } if (cg_timescale.value != cg_timescaleFadeEnd.value) { if (cg_timescale.value < cg_timescaleFadeEnd.value) { cg_timescale.value += cg_timescaleFadeSpeed.value * ((float)cg.frametime) / 1000; if (cg_timescale.value > cg_timescaleFadeEnd.value) cg_timescale.value = cg_timescaleFadeEnd.value; } else { cg_timescale.value -= cg_timescaleFadeSpeed.value * ((float)cg.frametime) / 1000; if (cg_timescale.value < cg_timescaleFadeEnd.value) cg_timescale.value = cg_timescaleFadeEnd.value; } if (cg_timescaleFadeSpeed.value) { trap_Cvar_SetValue("timescale", cg_timescale.value); } } // actually issue the rendering calls CG_DrawActive( stereoView ); } cg.cur_localPlayerNum = -1; cg.cur_lc = NULL; cg.cur_ps = NULL; // load any models that have been deferred if a scoreboard is shown if ( !CG_AnyScoreboardShowing() ) { cg.deferredPlayerLoading = 0; } else if ( ++cg.deferredPlayerLoading > 10 ) { CG_LoadDeferredPlayers(); } // if there are 3 viewports of equal size, fill the fourth quarter of the window if ( cg.numViewports == 3 && cg_splitviewThirdEqual.integer ) { // Setup forth viewport cg.numViewports = 4; cg.viewport = 3; // calculate size of viewport CG_CalcVrect(); CG_ClearViewport(); CG_DrawTourneyScoreboard(); } if (cg.numViewports != 1) { // Setup single viewport cg.numViewports = 1; cg.viewport = 0; // calculate size of viewport CG_CalcVrect(); } // Draw over all viewports CG_DrawScreen2D( stereoView ); if ( cg_stats.integer ) { CG_Printf( "cg.clientFrame:%i\n", cg.clientFrame ); } }