static void CalcPingRate(void) { extern cvar_t *info_rate; int rate = Cvar_ClampInteger(ui_pingrate, 0, 100); // assume average 450 bytes per reply packet if (!rate) rate = info_rate->integer / 450; // don't allow more than 100 packets/sec clamp(rate, 1, 100); // drop rate by stage m_servers.pingtime = (1000 * PING_STAGES) / (rate * m_servers.pingstage); }
static void ui_sortdemos_changed( cvar_t *self ) { int i = Cvar_ClampInteger( self, -COL_MAX, COL_MAX ); if( i > 0 ) { // ascending m_demos.list.sortdir = 1; m_demos.list.sortcol = i - 1; } else if( i < 0 ) { // descending m_demos.list.sortdir = -1; m_demos.list.sortcol = -i - 1; } else { // don't sort m_demos.list.sortdir = 0; m_demos.list.sortcol = 0; } if( m_demos.list.items && m_demos.list.sortdir ) { m_demos.list.sort( &m_demos.list, m_demos.list.sortcol ); } }
static void ui_sortservers_changed(cvar_t *self) { int i = Cvar_ClampInteger(self, -COL_MAX, COL_MAX); if (i > 0) { // ascending m_servers.list.sortdir = 1; m_servers.list.sortcol = i - 1; } else if (i < 0) { // descending m_servers.list.sortdir = -1; m_servers.list.sortcol = -i - 1; } else { // don't sort m_servers.list.sortdir = 1; m_servers.list.sortcol = -1; } if (m_servers.list.numItems) { m_servers.list.sort(&m_servers.list); } }
/* ============== SV_InitGame A brand new game has been started. If mvd_spawn is non-zero, load the built-in MVD game module. ============== */ void SV_InitGame( unsigned mvd_spawn ) { int i, entnum; edict_t *ent; client_t *client; if( svs.initialized ) { // cause any connected clients to reconnect SV_Shutdown( "Server restarted\n", ERR_RECONNECT | mvd_spawn ); } else { #if USE_CLIENT // make sure the client is down CL_Disconnect( ERR_RECONNECT ); SCR_BeginLoadingPlaque(); #endif CM_FreeMap( &sv.cm ); SV_FreeFile( sv.entitystring ); memset( &sv, 0, sizeof( sv ) ); #if USE_FPS // set up default frametime for main loop sv.frametime = BASE_FRAMETIME; #endif } // get any latched variable changes (maxclients, etc) Cvar_GetLatchedVars (); #if !USE_CLIENT Cvar_Reset( sv_recycle ); #endif if( mvd_spawn ) { Cvar_Set( "deathmatch", "1" ); Cvar_Set( "coop", "0" ); } else { if( Cvar_VariableInteger( "coop" ) && Cvar_VariableInteger( "deathmatch" ) ) { Com_Printf( "Deathmatch and Coop both set, disabling Coop\n" ); Cvar_Set( "coop", "0" ); } // dedicated servers can't be single player and are usually DM // so unless they explicity set coop, force it to deathmatch if( Com_IsDedicated() ) { if( !Cvar_VariableInteger( "coop" ) ) Cvar_Set( "deathmatch", "1" ); } } // init clients if( Cvar_VariableInteger( "deathmatch" ) ) { if( sv_maxclients->integer <= 1 ) { Cvar_SetInteger( sv_maxclients, 8, FROM_CODE ); } else if( sv_maxclients->integer > CLIENTNUM_RESERVED ) { Cvar_SetInteger( sv_maxclients, CLIENTNUM_RESERVED, FROM_CODE ); } } else if( Cvar_VariableInteger( "coop" ) ) { if( sv_maxclients->integer <= 1 || sv_maxclients->integer > 4 ) Cvar_Set( "maxclients", "4" ); } else { // non-deathmatch, non-coop is one player Cvar_FullSet( "maxclients", "1", CVAR_SERVERINFO|CVAR_LATCH, FROM_CODE ); } // enable networking if( sv_maxclients->integer > 1 ) { NET_Config( NET_SERVER ); } svs.client_pool = SV_Mallocz( sizeof( client_t ) * sv_maxclients->integer ); svs.num_entities = sv_maxclients->integer * UPDATE_BACKUP * MAX_PACKET_ENTITIES; svs.entities = SV_Mallocz( sizeof( entity_state_t ) * svs.num_entities ); #if USE_MVD_SERVER // initialize MVD server if( !mvd_spawn ) { SV_MvdInit(); } #endif Cvar_ClampInteger( sv_reserved_slots, 0, sv_maxclients->integer - 1 ); #if USE_ZLIB svs.z.zalloc = SV_Zalloc; svs.z.zfree = SV_Zfree; if( deflateInit2( &svs.z, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 9, Z_DEFAULT_STRATEGY ) != Z_OK ) { Com_Error( ERR_FATAL, "%s: deflateInit2() failed", __func__ ); } #endif // init game #if USE_MVD_CLIENT if( mvd_spawn ) { if( ge ) { SV_ShutdownGameProgs(); } ge = &mvd_ge; ge->Init(); } else #endif SV_InitGameProgs(); // send heartbeat very soon svs.last_heartbeat = -(HEARTBEAT_SECONDS-5)*1000; for( i = 0; i < sv_maxclients->integer; i++ ) { client = svs.client_pool + i; entnum = i + 1; ent = EDICT_NUM( entnum ); ent->s.number = entnum; client->edict = ent; client->number = i; } #if USE_AC_SERVER AC_Connect( mvd_spawn ); #endif svs.initialized = qtrue; }
/* ================= Qcommon_Frame ================= */ void Qcommon_Frame(void) { #if USE_CLIENT unsigned time_before, time_event, time_between, time_after; unsigned clientrem; #endif unsigned oldtime, msec; static unsigned remaining; static float frac; if (setjmp(abortframe)) { return; // an ERR_DROP was thrown } #if USE_CLIENT time_before = time_event = time_between = time_after = 0; if (host_speeds->integer) time_before = Sys_Milliseconds(); #endif // sleep on network sockets when running a dedicated server // still do a select(), but don't sleep when running a client! NET_Sleep(remaining); // calculate time spent running last frame and sleeping oldtime = com_eventTime; com_eventTime = Sys_Milliseconds(); if (oldtime > com_eventTime) { oldtime = com_eventTime; } msec = com_eventTime - oldtime; #if USE_CLIENT // spin until msec is non-zero if running a client if (!dedicated->integer && !com_timedemo->integer) { while (msec < 1) { qboolean break_now = CL_ProcessEvents(); com_eventTime = Sys_Milliseconds(); msec = com_eventTime - oldtime; if (break_now) break; } } #endif if (msec > 250) { Com_DPrintf("Hitch warning: %u msec frame time\n", msec); msec = 100; // time was unreasonable, // host OS was hibernated or something } if (fixedtime->integer) { Cvar_ClampInteger(fixedtime, 1, 1000); msec = fixedtime->integer; } else if (timescale->value > 0) { frac += msec * timescale->value; msec = frac; frac -= msec; } // run local time com_localTime += msec; com_framenum++; #if USE_CLIENT if (host_speeds->integer) time_event = Sys_Milliseconds(); #endif // run system console Sys_RunConsole(); NET_UpdateStats(); remaining = SV_Frame(msec); #if USE_CLIENT if (host_speeds->integer) time_between = Sys_Milliseconds(); clientrem = CL_Frame(msec); if (remaining > clientrem) { remaining = clientrem; } if (host_speeds->integer) time_after = Sys_Milliseconds(); if (host_speeds->integer) { int all, ev, sv, gm, cl, rf; all = time_after - time_before; ev = time_event - time_before; sv = time_between - time_event; cl = time_after - time_between; gm = time_after_game - time_before_game; rf = time_after_ref - time_before_ref; sv -= gm; cl -= rf; Com_Printf("all:%3i ev:%3i sv:%3i gm:%3i cl:%3i rf:%3i\n", all, ev, sv, gm, cl, rf); } #endif }
static int LoadGL(const char *driver) { int colorbits = Cvar_ClampInteger(gl_colorbits, 0, 32); int depthbits = Cvar_ClampInteger(gl_depthbits, 0, 32); int stencilbits = Cvar_ClampInteger(gl_stencilbits, 0, 8); int multisamples = Cvar_ClampInteger(gl_multisamples, 0, 32); int ret; // figure out if we're running on a minidriver or not if (!Q_stricmp(driver, "opengl32") || !Q_stricmp(driver, "opengl32.dll")) { glw.minidriver = qfalse; } else { Com_Printf("...running a minidriver: %s\n", driver); glw.minidriver = qtrue; } // load the OpenGL library and bind to it if (!WGL_Init(driver)) { ReportLastError("WGL_Init"); return FAIL_SOFT; } // check if basic WGL entry points are present if (!qwglCreateContext || !qwglMakeCurrent || !qwglDeleteContext) { Com_EPrintf("Required WGL entry points are missing\n"); goto fail; } if (glw.minidriver) { // check if MCD entry points are present if using a minidriver if (!qwglChoosePixelFormat || !qwglSetPixelFormat || !qwglDescribePixelFormat || !qwglSwapBuffers) { Com_EPrintf("Required MCD entry points are missing\n"); goto fail; } } // check for WGL_ARB_multisample by creating a fake window if (multisamples > 1) { unsigned extensions = GetFakeWindowExtensions(); if (extensions & QWGL_ARB_multisample) { if (qwglChoosePixelFormatARB) { Com_Printf("...enabling WGL_ARB_multisample\n"); } else { Com_Printf("...ignoring WGL_ARB_multisample, WGL_ARB_pixel_format not found\n"); Cvar_Set("gl_multisamples", "0"); multisamples = 0; } } else { Com_Printf("WGL_ARB_multisample not found\n"); Cvar_Set("gl_multisamples", "0"); multisamples = 0; } } // create window, choose PFD, setup OpenGL context ret = SetupGL(colorbits, depthbits, stencilbits, multisamples); // attempt to recover if (ret == FAIL_SOFT && (colorbits || depthbits || stencilbits || multisamples > 1)) { Cvar_Set("gl_multisamples", "0"); ret = SetupGL(0, 0, 0, 0); } if (ret) goto fail; return FAIL_OK; fail: // it failed, clean up WGL_Shutdown(); return FAIL_SOFT; }
/* ================= CL_SendBatchedCmd ================= */ static void CL_SendBatchedCmd( void ) { int i, j, seq, bits; int numCmds, numDups; int totalCmds, totalMsec; size_t cursize; usercmd_t *cmd, *oldcmd; client_history_t *history, *oldest; byte *patch; // see if we are ready to send this packet if( !ready_to_send() ) { return; } // archive this packet seq = cls.netchan->outgoing_sequence; history = &cl.history[seq & CMD_MASK]; history->cmdNumber = cl.cmdNumber; history->sent = cls.realtime; // for ping calculation history->rcvd = 0; cl.lastTransmitTime = cls.realtime; cl.lastTransmitCmdNumber = cl.cmdNumber; cl.lastTransmitCmdNumberReal = cl.cmdNumber; // begin a client move command patch = SZ_GetSpace( &msg_write, 1 ); // let the server know what the last frame we // got was, so the next message can be delta compressed if( cl_nodelta->integer || !cl.frame.valid /*|| cls.demowaiting*/ ) { *patch = clc_move_nodelta; // no compression } else { *patch = clc_move_batched; MSG_WriteLong( cl.frame.number ); } Cvar_ClampInteger( cl_packetdup, 0, MAX_PACKET_FRAMES - 1 ); numDups = cl_packetdup->integer; *patch |= numDups << SVCMD_BITS; // send lightlevel MSG_WriteByte( cl.lightlevel ); // send this and the previous cmds in the message, so // if the last packet was dropped, it can be recovered oldcmd = NULL; totalCmds = 0; totalMsec = 0; for( i = seq - numDups; i <= seq; i++ ) { oldest = &cl.history[( i - 1 ) & CMD_MASK]; history = &cl.history[i & CMD_MASK]; numCmds = history->cmdNumber - oldest->cmdNumber; if( numCmds >= MAX_PACKET_USERCMDS ) { Com_WPrintf( "%s: MAX_PACKET_USERCMDS exceeded\n", __func__ ); SZ_Clear( &msg_write ); break; } totalCmds += numCmds; MSG_WriteBits( numCmds, 5 ); for( j = oldest->cmdNumber + 1; j <= history->cmdNumber; j++ ) { cmd = &cl.cmds[j & CMD_MASK]; totalMsec += cmd->msec; bits = MSG_WriteDeltaUsercmd_Enhanced( oldcmd, cmd, cls.protocolVersion ); #ifdef _DEBUG if( cl_showpackets->integer == 3 ) { MSG_ShowDeltaUsercmdBits_Enhanced( bits ); } #endif oldcmd = cmd; } } P_FRAMES++; // // deliver the message // cursize = cls.netchan->Transmit( cls.netchan, msg_write.cursize, msg_write.data, 1 ); #ifdef _DEBUG if( cl_showpackets->integer == 1 ) { Com_Printf( "%"PRIz"(%i) ", cursize, totalCmds ); } else if( cl_showpackets->integer == 2 ) { Com_Printf( "%"PRIz"(%i) ", cursize, totalMsec ); } else if( cl_showpackets->integer == 3 ) { Com_Printf( " | " ); } #endif SZ_Clear( &msg_write ); }
/* =============== R_SetupFrame =============== */ void R_SetupFrame(void) { int i; vrect_t vrect; if (r_fullbright->modified) { r_fullbright->modified = qfalse; D_FlushCaches(); // so all lighting changes } r_framecount++; // build the transformation matrix for the given view angles VectorCopy(r_newrefdef.vieworg, modelorg); VectorCopy(r_newrefdef.vieworg, r_origin); AngleVectors(r_newrefdef.viewangles, vpn, vright, vup); // current viewleaf if (!(r_newrefdef.rdflags & RDF_NOWORLDMODEL)) { r_viewleaf = BSP_PointLeaf(r_worldmodel->nodes, r_origin); r_viewcluster = r_viewleaf->cluster; } if (sw_waterwarp->integer && (r_newrefdef.rdflags & RDF_UNDERWATER)) r_dowarp = qtrue; else r_dowarp = qfalse; if (r_dowarp) { // warp into off screen buffer vrect.x = 0; vrect.y = 0; vrect.width = r_newrefdef.width < WARP_WIDTH ? r_newrefdef.width : WARP_WIDTH; vrect.height = r_newrefdef.height < WARP_HEIGHT ? r_newrefdef.height : WARP_HEIGHT; d_viewbuffer = r_warpbuffer; d_screenrowbytes = WARP_WIDTH * VID_BYTES; } else { vrect.x = r_newrefdef.x; vrect.y = r_newrefdef.y; vrect.width = r_newrefdef.width; vrect.height = r_newrefdef.height; d_viewbuffer = (void *)vid.buffer; d_screenrowbytes = vid.rowbytes; } R_ViewChanged(&vrect); // start off with just the four screen edge clip planes R_TransformFrustum(); R_SetUpFrustumIndexes(); // save base values VectorCopy(vpn, base_vpn); VectorCopy(vright, base_vright); VectorCopy(vup, base_vup); // clear frame counts c_faceclip = 0; r_polycount = 0; r_drawnpolycount = 0; r_wholepolycount = 0; r_amodels_drawn = 0; r_outofsurfaces = 0; r_outofedges = 0; // d_setup for (i = 0; i < vid.height; i++) { d_spantable[i] = d_viewbuffer + i * d_screenrowbytes; d_zspantable[i] = d_pzbuffer + i * d_zwidth; } // clear Z-buffer and color-buffers if we're doing the gallery if (r_newrefdef.rdflags & RDF_NOWORLDMODEL) { memset(d_pzbuffer, 0xff, vid.width * vid.height * sizeof(d_pzbuffer[0])); #if 0 R_DrawFill8(r_newrefdef.x, r_newrefdef.y, r_newrefdef.width, r_newrefdef.height, /*(int)sw_clearcolor->value & 0xff*/0); #endif } d_minmip = Cvar_ClampInteger(sw_mipcap, 0, NUM_MIPS - 1); for (i = 0; i < (NUM_MIPS - 1); i++) d_scalemip[i] = basemip[i] * sw_mipscale->value; }