void VEngine::Init() { InitStaticData(); if( ParseParam(appCmdLine(), TEXT("FIXEDSEED")) ) { appRandInit(0); } else { appRandInit(appCycles()); } // Init client _GameClient = Cast<VWindowClient>(VObject::StaticConstructObject(_GameViewportClass)); _GameClient->Init(); // Init GameViewport VGameViewportClientPtr ViewportClient = NULL; if( _GameClient ) { ViewportClient = Cast<VGameViewportClient>(VObject::StaticConstructObject(_GameClientClass)); _GameViewport = ViewportClient; } if( ViewportClient ) { FString Error; if( !ViewportClient->Init(Error) ) { appErrorf(TEXT("%s"), Error.c_str()); return; } FViewport* Viewport = _GameClient->CreateViewport(ViewportClient, TEXT("Product"), 800, 600, FALSE); _GameViewport->SetViewport(Viewport); } GLog->Log(NAME_Init, TEXT("Game engine initialized")); }
void SV_Frame(float msec) { guard(SV_Frame); time_before_game = time_after_game = 0; // if server is not active, do nothing if (!svs.initialized) return; // SV_DrawTextLeft(va("time: %10d rf: %10.5f d: %10.4f ri:%10d", sv.time, svs.realtimef, msec, svs.realtime));//!! svs.realtimef += msec; svs.realtime = appFloor(svs.realtimef); if (!sv.attractloop) { // check timeouts SV_CheckTimeouts(); } // get packets from clients SV_ReadPackets(); if (sv.state == ss_dead) return; // server was killed from one of packet (e.g. "rcon killserver") int frameTime = 100; // (sv_fps->integer > 10) ? (1000 / sv_fps->integer) : 100; // move autonomous things around if enough time has passed if (svs.realtime < sv.time) { // never let the time get too far off if (sv.time - svs.realtime > frameTime) { if (sv_showclamp->integer) appPrintf("sv lowclamp s:%d -- r:%d -> %d\n", sv.time, svs.realtime, sv.time - frameTime); svs.realtime = sv.time - frameTime; svs.realtimef = svs.realtime; } return; } SV_ClearTexts(); if (!sv.attractloop) { // update ping based on the last known frame from all clients SV_CalcPings(); // give the clients some timeslices SV_GiveMsec(); } // let everything in the world think and move /*-------- SV_RunGameFrame() ---------------*/ // we always need to bump framenum, even if we // don't run the world, otherwise the delta // compression can get confused when a client // has the "current" frame sv.framenum++; sv.time += frameTime; // = sv.framenum*100; ?? // don't run if paused if (!sv_paused->integer || sv_maxclients->integer > 1) { time_before_game = appCycles(); guardGame(ge.RunFrame); ge->RunFrame(); unguardGame; // never get more than one tic behind if (sv.time < svs.realtime) { if (sv_showclamp->integer) appPrintf("sv highclamp s:%d r:%d -> %d\n", sv.time, svs.realtime, sv.time); svs.realtime = sv.time; svs.realtimef = sv.time; } time_after_game = appCycles(); } // if extended protocol used, recalculate footstep sounds, mdx/mdl/md3 frames etc. if (sv_extProtocol->integer && !sv.attractloop) SV_PostprocessFrame(); // send messages back to the clients that had packets read this frame SV_SendClientMessages(); // save the entire world state if recording a serverdemo SV_RecordDemoMessage(); // send a heartbeat to the master if needed Master_Heartbeat(); // clear teleport flags, etc for next frame SV_PrepWorldFrame(); unguard; }
bool V_RenderView() { guard(V_RenderView); if (cls.state != ca_active) return false; if (!cl.rendererReady) return false; // still loading if (!bspfile.clientLoaded) return false; // map already unloaded (by server), but client is still active (ca_active) if (timedemo->integer) { static unsigned lastTime = 0; unsigned time = appMilliseconds(); if (!cl.timedemoStart) { cl.timedemoStart = time; // cl.timedemoLongestFrame = 0; -- cleared anyway within a new server map // cl.timedemoFrames = 0; } else { unsigned timeDelta = time - lastTime; if (timeDelta > cl.timedemoLongestFrame) //?? && !fileFromPak) cl.timedemoLongestFrame = timeDelta; } lastTime = time; cl.timedemoFrames++; } #if PROFILE_VIEW unsigned beforePrep = 0, beforeDebug = 0, beforeEffects = 0, afterEffects = 0, beforeRender, afterRender; #endif // an invalid frame will just use the exact previous refdef // we can't use the old frame if the video mode has changed, though... if (cl.frame.valid && (cl.forceViewFrame || !cl_paused->integer)) { PRF(beforePrep = appCycles()); cl.forceViewFrame = false; CalcVrect(); TileClear(); V_ClearScene(); cl.refdef.rdflags = cl.frame.playerstate.rdflags; // build a renderer entity list and calc cl.sim* // this also calls CL_CalcViewValues which loads // v_forward, etc. CL_AddEntities(); PRF(beforeEffects = appCycles()); CL_AddEffects(); PRF(afterEffects = appCycles()); CL_AddTEnts(); #if !NO_DEBUG if (cl_testentities->integer) TestEntities(); if (cl_testlights->integer) TestLights(); if (cl_testblend->integer) { r_blend[0] = 1; r_blend[1] = 0.5; r_blend[2] = 0.25; r_blend[3] = 0.5; } // debug output // free debug memory from previous frame if (debugMem) { delete debugMem; debugMem = NULL; } PRF(beforeDebug = appCycles()); if (r_playerpos->integer) DrawOriginInfo(); if (r_surfinfo->integer) DrawSurfInfo(); DrawBrush(); #endif // NO_DEBUG #if 0 // never let it sit exactly on a node line, because a water plane can // dissapear when viewed with the eye exactly on it. // the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis cl.refdef.vieworg[0] += 1.0f/16; //?? cl.refdef.vieworg[1] += 1.0f/16; cl.refdef.vieworg[2] += 1.0f/16; #endif 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 = CalcFov(cl.refdef.fov_x, cl.refdef.width, cl.refdef.height); cl.refdef.time = cl.ftime; cl.refdef.zonebits = cl.frame.zonebits; if (!cl_add_entities->integer) r_numentities = 0; if (!cl_add_lights->integer) r_numdlights = 0; if (!cl_add_blend->integer || cl.refdef.rdflags & RDF_THIRD_PERSON) r_blend[3] = 0; cl.refdef.num_entities = r_numentities; cl.refdef.entities = r_entities; cl.refdef.particles = cl_add_particles->integer ? active_particles : NULL; cl.refdef.beams = active_beams; cl.refdef.num_dlights = r_numdlights; cl.refdef.dlights = r_dlights; cl.refdef.lightstyles = cl_lightstyles; // underwater fov warp (taken from Q3 game source) if (cl.refdef.rdflags & RDF_UNDERWATER) { float v = sin(cl.ftime * 0.4f * M_PI * 2); cl.refdef.fov_x += v; cl.refdef.fov_y -= v; } FixWaterVis(); } PRF(beforeRender = appCycles()); // render scene RE_RenderFrame(&cl.refdef); PRF(afterRender = appCycles()); // add full-screen blend if (r_blend[3]) RE_Fill(cl.refdef.x, cl.refdef.y, cl.refdef.width, cl.refdef.height, RGBAS(r_blend[0], r_blend[1], r_blend[2], r_blend[3])); #if PROFILE_VIEW RE_DrawTextLeft(va("V: prep1: %5.2f fx: %5.2f prep2: %5.2f dbg: %5.2f render: %5.2f", appCyclesToMsecf(beforeEffects - beforePrep), appCyclesToMsecf(afterEffects - beforeEffects), appCyclesToMsecf(beforeDebug - afterEffects), appCyclesToMsecf(beforeRender - beforeDebug), appCyclesToMsecf(afterRender - beforeRender)), RGB(0.2,1,0.2)); #endif // stats if (r_drawfps->integer) DrawFpsInfo(); return true; unguard; }