[quake3-commits] r1835 - in trunk: . code/null code/qcommon code/server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Wed Feb 2 11:46:23 EST 2011


Author: thilo
Date: 2011-02-02 11:46:23 -0500 (Wed, 02 Feb 2011)
New Revision: 1835

Modified:
   trunk/README
   trunk/code/null/mac_net.c
   trunk/code/null/null_net.c
   trunk/code/qcommon/common.c
   trunk/code/qcommon/net_ip.c
   trunk/code/qcommon/qcommon.h
   trunk/code/server/sv_main.c
Log:
- Use select() to sleep when idle as opposed to busy waiting.
- Introduce com_busyWait cvar to go back to old behaviour


Modified: trunk/README
===================================================================
--- trunk/README	2011-01-31 22:09:47 UTC (rev 1834)
+++ trunk/README	2011-02-02 16:46:23 UTC (rev 1835)
@@ -144,7 +144,8 @@
   com_standalone                    - Run in standalone mode
   com_maxfpsUnfocused               - Maximum frames per second when unfocused
   com_maxfpsMinimized               - Maximum frames per second when minimized
-
+  com_busyWait                      - Will use a busy loop to wait for rendering
+                                      next frame when set to non-zero value.
   in_joystickNo                     - select which joystick to use
   in_keyboardDebug                  - print keyboard debug info
 
@@ -235,6 +236,16 @@
   data, nor is it something that we like to spend much time maintaining or
   supporting.
 
+Help! Ioquake3 won't give me an fps of X anymore when setting com_maxfps!
+  Ioquake3 now uses the select() system call to wait for the rendering of the
+  next frame when com_maxfps was hit. This will improve your CPU load
+  considerably in these cases. However, not all systems may support a
+  granularity for its timing functions that is required to perform this waiting
+  correctly. For instance, ioquake3 tells select() to wait 2 milliseconds, but
+  really it can only wait for a multiple of 5ms, i.e. 5, 10, 15, 20... ms.
+  In this case you can always revert back to the old behaviour by setting the
+  cvar com_busyWait to 1.
+
 QuakeLive mouse acceleration (patch and this text written by TTimo from id)
   I've been using an experimental mouse acceleration code for a while, and
   decided to make it available to everyone. Don't be too worried if you don't

Modified: trunk/code/null/mac_net.c
===================================================================
--- trunk/code/null/mac_net.c	2011-01-31 22:09:47 UTC (rev 1834)
+++ trunk/code/null/mac_net.c	2011-02-02 16:46:23 UTC (rev 1835)
@@ -52,14 +52,3 @@
 */
 void Sys_SendPacket( int length, void *data, netadr_t to ) {
 }
-
-/*
-==================
-Sys_GetPacket
-
-Never called by the game logic, just the system event queing
-==================
-*/
-qboolean	Sys_GetPacket ( netadr_t *net_from, msg_t *net_message ) {
-	return false;
-}

Modified: trunk/code/null/null_net.c
===================================================================
--- trunk/code/null/null_net.c	2011-01-31 22:09:47 UTC (rev 1834)
+++ trunk/code/null/null_net.c	2011-02-02 16:46:23 UTC (rev 1835)
@@ -51,14 +51,3 @@
 */
 void Sys_SendPacket( int length, void *data, netadr_t to ) {
 }
-
-/*
-==================
-Sys_GetPacket
-
-Never called by the game logic, just the system event queing
-==================
-*/
-qboolean	Sys_GetPacket ( netadr_t *net_from, msg_t *net_message ) {
-	return false;
-}

Modified: trunk/code/qcommon/common.c
===================================================================
--- trunk/code/qcommon/common.c	2011-01-31 22:09:47 UTC (rev 1834)
+++ trunk/code/qcommon/common.c	2011-02-02 16:46:23 UTC (rev 1835)
@@ -59,7 +59,6 @@
 cvar_t	*com_dedicated;
 cvar_t	*com_timescale;
 cvar_t	*com_fixedtime;
-cvar_t	*com_dropsim;		// 0.0 to 1.0, simulated packet drops
 cvar_t	*com_journal;
 cvar_t	*com_maxfps;
 cvar_t	*com_altivec;
@@ -84,6 +83,7 @@
 cvar_t	*com_maxfpsMinimized;
 cvar_t	*com_abnormalExit;
 cvar_t	*com_standalone;
+cvar_t	*com_busyWait;
 
 // com_speeds times
 int		time_game;
@@ -91,7 +91,6 @@
 int		time_backend;		// renderer backend time
 
 int			com_frameTime;
-int			com_frameMsec;
 int			com_frameNumber;
 
 qboolean	com_errorEntered = qfalse;
@@ -1945,7 +1944,6 @@
 static sysEvent_t  eventQueue[ MAX_QUEUED_EVENTS ];
 static int         eventHead = 0;
 static int         eventTail = 0;
-static byte        sys_packetReceived[ MAX_MSGLEN ];
 
 /*
 ================
@@ -1998,8 +1996,6 @@
 {
 	sysEvent_t  ev;
 	char        *s;
-	msg_t       netmsg;
-	netadr_t    adr;
 
 	// return if we have data
 	if ( eventHead > eventTail )
@@ -2021,21 +2017,6 @@
 		Com_QueueEvent( 0, SE_CONSOLE, 0, 0, len, b );
 	}
 
-	// check for network packets
-	MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
-	if ( Sys_GetPacket ( &adr, &netmsg ) )
-	{
-		netadr_t  *buf;
-		int       len;
-
-		// copy out to a seperate buffer for qeueing
-		len = sizeof( netadr_t ) + netmsg.cursize;
-		buf = Z_Malloc( len );
-		*buf = adr;
-		memcpy( buf+1, netmsg.data, netmsg.cursize );
-		Com_QueueEvent( 0, SE_PACKET, 0, 0, len, buf );
-	}
-
 	// return if we have data
 	if ( eventHead > eventTail )
 	{
@@ -2195,7 +2176,6 @@
 	MSG_Init( &buf, bufData, sizeof( bufData ) );
 
 	while ( 1 ) {
-		NET_FlushPacketQueue();
 		ev = Com_GetEvent();
 
 		// if no more events are available
@@ -2216,58 +2196,27 @@
 		}
 
 
-		switch ( ev.evType ) {
-		default:
-			Com_Error( ERR_FATAL, "Com_EventLoop: bad event type %i", ev.evType );
+		switch(ev.evType)
+		{
+			case SE_KEY:
+				CL_KeyEvent( ev.evValue, ev.evValue2, ev.evTime );
 			break;
-        case SE_NONE:
-            break;
-		case SE_KEY:
-			CL_KeyEvent( ev.evValue, ev.evValue2, ev.evTime );
+			case SE_CHAR:
+				CL_CharEvent( ev.evValue );
 			break;
-		case SE_CHAR:
-			CL_CharEvent( ev.evValue );
+			case SE_MOUSE:
+				CL_MouseEvent( ev.evValue, ev.evValue2, ev.evTime );
 			break;
-		case SE_MOUSE:
-			CL_MouseEvent( ev.evValue, ev.evValue2, ev.evTime );
+			case SE_JOYSTICK_AXIS:
+				CL_JoystickEvent( ev.evValue, ev.evValue2, ev.evTime );
 			break;
-		case SE_JOYSTICK_AXIS:
-			CL_JoystickEvent( ev.evValue, ev.evValue2, ev.evTime );
+			case SE_CONSOLE:
+				Cbuf_AddText( (char *)ev.evPtr );
+				Cbuf_AddText( "\n" );
 			break;
-		case SE_CONSOLE:
-			Cbuf_AddText( (char *)ev.evPtr );
-			Cbuf_AddText( "\n" );
+			default:
+				Com_Error( ERR_FATAL, "Com_EventLoop: bad event type %i", ev.evType );
 			break;
-		case SE_PACKET:
-			// this cvar allows simulation of connections that
-			// drop a lot of packets.  Note that loopback connections
-			// don't go through here at all.
-			if ( com_dropsim->value > 0 ) {
-				static int seed;
-
-				if ( Q_random( &seed ) < com_dropsim->value ) {
-					break;		// drop this packet
-				}
-			}
-
-			evFrom = *(netadr_t *)ev.evPtr;
-			buf.cursize = ev.evPtrLength - sizeof( evFrom );
-
-			// we must copy the contents of the message out, because
-			// the event buffers are only large enough to hold the
-			// exact payload, but channel messages need to be large
-			// enough to hold fragment reassembly
-			if ( (unsigned)buf.cursize > buf.maxsize ) {
-				Com_Printf("Com_EventLoop: oversize packet\n");
-				continue;
-			}
-			Com_Memcpy( buf.data, (byte *)((netadr_t *)ev.evPtr + 1), buf.cursize );
-			if ( com_sv_running->integer ) {
-				Com_RunAndTimeServerPacket( &evFrom, &buf );
-			} else {
-				CL_PacketEvent( evFrom, &buf );
-			}
-			break;
 		}
 
 		// free any block data
@@ -2639,7 +2588,6 @@
 
 	// Clear queues
 	Com_Memset( &eventQueue[ 0 ], 0, MAX_QUEUED_EVENTS * sizeof( sysEvent_t ) );
-	Com_Memset( &sys_packetReceived[ 0 ], 0, MAX_MSGLEN * sizeof( byte ) );
 
 	// initialize the weak pseudo-random number generator for use later.
 	Com_InitRand();
@@ -2720,7 +2668,6 @@
 	com_timescale = Cvar_Get ("timescale", "1", CVAR_CHEAT | CVAR_SYSTEMINFO );
 	com_fixedtime = Cvar_Get ("fixedtime", "0", CVAR_CHEAT);
 	com_showtrace = Cvar_Get ("com_showtrace", "0", CVAR_CHEAT);
-	com_dropsim = Cvar_Get ("com_dropsim", "0", CVAR_CHEAT);
 	com_speeds = Cvar_Get ("com_speeds", "0", 0);
 	com_timedemo = Cvar_Get ("timedemo", "0", CVAR_CHEAT);
 	com_cameraMode = Cvar_Get ("com_cameraMode", "0", CVAR_CHEAT);
@@ -2740,6 +2687,7 @@
 	com_maxfpsMinimized = Cvar_Get( "com_maxfpsMinimized", "0", CVAR_ARCHIVE );
 	com_abnormalExit = Cvar_Get( "com_abnormalExit", "0", CVAR_ROM );
 	com_standalone = Cvar_Get( "com_standalone", "0", CVAR_INIT );
+	com_busyWait = Cvar_Get("com_busyWait", "0", CVAR_ARCHIVE);
 
 	com_introPlayed = Cvar_Get( "com_introplayed", "0", CVAR_ARCHIVE);
 
@@ -2947,19 +2895,16 @@
 void Com_Frame( void ) {
 
 	int		msec, minMsec;
-	static int	lastTime;
-	int key;
+	int		timeVal;
+	static int	lastTime = 0;
  
 	int		timeBeforeFirstEvents;
-	int           timeBeforeServer;
-	int           timeBeforeEvents;
-	int           timeBeforeClient;
-	int           timeAfter;
+	int		timeBeforeServer;
+	int		timeBeforeEvents;
+	int		timeBeforeClient;
+	int		timeAfter;
   
 
-
-
-
 	if ( setjmp (abortframe) ) {
 		return;			// an ERR_DROP was thrown
 	}
@@ -2970,10 +2915,6 @@
 	timeBeforeClient = 0;
 	timeAfter = 0;
 
-
-	// old net chan encryption key
-	key = 0x87243987;
-
 	// write config file if anything changed
 	Com_WriteConfiguration(); 
 
@@ -2984,37 +2925,62 @@
 		timeBeforeFirstEvents = Sys_Milliseconds ();
 	}
 
-	// we may want to spin here if things are going too fast
-	if ( !com_dedicated->integer && !com_timedemo->integer ) {
-		if( com_minimized->integer && com_maxfpsMinimized->integer > 0 ) {
-			minMsec = 1000 / com_maxfpsMinimized->integer;
-		} else if( com_unfocused->integer && com_maxfpsUnfocused->integer > 0 ) {
-			minMsec = 1000 / com_maxfpsUnfocused->integer;
-		} else if( com_maxfps->integer > 0 ) {
-			minMsec = 1000 / com_maxfps->integer;
-		} else {
-			minMsec = 1;
+	// Figure out how much time we have
+	if(!com_timedemo->integer)
+	{
+		if(com_dedicated->integer)
+			minMsec = SV_FrameMsec();
+		else
+		{
+			if(com_minimized->integer && com_maxfpsMinimized->integer > 0)
+				minMsec = 1000 / com_maxfpsMinimized->integer;
+			else if(com_unfocused->integer && com_maxfpsUnfocused->integer > 0)
+				minMsec = 1000 / com_maxfpsUnfocused->integer;
+			else if(com_maxfps->integer > 0)
+				minMsec = 1000 / com_maxfps->integer;
+			else
+				minMsec = 1;
+			
+			timeVal = com_frameTime - lastTime;
+			if(timeVal > minMsec)
+			{
+				// Adjust minMsec if previous frame took too long to render so
+				// that framerate is stable at the requested value.
+				timeVal -= minMsec;
+
+				if(timeVal > minMsec)
+					minMsec = 0;
+				else
+					minMsec -= timeVal;
+			}
+			
 		}
-	} else {
-		minMsec = 1;
 	}
+	else
+		minMsec = 1;
 
-	msec = minMsec;
-	do {
-		int timeRemaining = minMsec - msec;
+	timeVal = 0;
+	do
+	{
+		if(com_busyWait->integer)
+			NET_Sleep(0);
+		else
+			NET_Sleep(timeVal);
 
-		// The existing Sys_Sleep implementations aren't really
-		// precise enough to be of use beyond 100fps
-		// FIXME: implement a more precise sleep (RDTSC or something)
-		if( timeRemaining >= 10 )
-			Sys_Sleep( timeRemaining );
+		msec = Sys_Milliseconds() - com_frameTime;
+		
+		if(msec >= minMsec)
+			timeVal = 0;
+		else
+			timeVal = minMsec - msec;
 
-		com_frameTime = Com_EventLoop();
-		if ( lastTime > com_frameTime ) {
-			lastTime = com_frameTime;		// possible on first frame
-		}
-		msec = com_frameTime - lastTime;
-	} while ( msec < minMsec );
+	} while(timeVal > 0);
+	
+	lastTime = com_frameTime;
+	com_frameTime = Com_EventLoop();
+	
+	msec = com_frameTime - lastTime;
+
 	Cbuf_Execute ();
 
 	if (com_altivec->modified)
@@ -3023,11 +2989,8 @@
 		com_altivec->modified = qfalse;
 	}
 
-	lastTime = com_frameTime;
-
 	// mess with msec if needed
-	com_frameMsec = msec;
-	msec = Com_ModifyMsec( msec );
+	msec = Com_ModifyMsec(msec);
 
 	//
 	// server side
@@ -3087,6 +3050,9 @@
 	}
 #endif
 
+
+	NET_FlushPacketQueue();
+
 	//
 	// report timing information
 	//
@@ -3120,9 +3086,6 @@
 		c_pointcontents = 0;
 	}
 
-	// old net chan encryption key
-	key = lastTime * 0x87243987;
-
 	com_frameNumber++;
 }
 

Modified: trunk/code/qcommon/net_ip.c
===================================================================
--- trunk/code/qcommon/net_ip.c	2011-01-31 22:09:47 UTC (rev 1834)
+++ trunk/code/qcommon/net_ip.c	2011-02-02 16:46:23 UTC (rev 1835)
@@ -107,6 +107,8 @@
 static cvar_t	*net_mcast6addr;
 static cvar_t	*net_mcast6iface;
 
+static cvar_t	*net_dropsim;
+
 static struct sockaddr	socksRelayAddr;
 
 static SOCKET	ip_socket = INVALID_SOCKET;
@@ -201,7 +203,7 @@
 		default: return "NO ERROR";
 	}
 #else
-	return strerror (errno);
+	return strerror(socketError);
 #endif
 }
 
@@ -524,16 +526,17 @@
 
 /*
 ==================
-Sys_GetPacket
+NET_GetPacket
 
-Never called by the game logic, just the system event queing
+Receive one packet
 ==================
 */
 #ifdef _DEBUG
 int	recvfromCount;
 #endif
 
-qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
+qboolean NET_GetPacket(netadr_t *net_from, msg_t *net_message, fd_set *fdr)
+{
 	int 	ret;
 	struct sockaddr_storage from;
 	socklen_t	fromlen;
@@ -543,7 +546,7 @@
 	recvfromCount++;		// performance check
 #endif
 	
-	if(ip_socket != INVALID_SOCKET)
+	if(ip_socket != INVALID_SOCKET && FD_ISSET(ip_socket, fdr))
 	{
 		fromlen = sizeof(from);
 		ret = recvfrom( ip_socket, (void *)net_message->data, net_message->maxsize, 0, (struct sockaddr *) &from, &fromlen );
@@ -577,7 +580,7 @@
 				net_message->readcount = 0;
 			}
 		
-			if( ret == net_message->maxsize ) {
+			if( ret >= net_message->maxsize ) {
 				Com_Printf( "Oversize packet from %s\n", NET_AdrToString (*net_from) );
 				return qfalse;
 			}
@@ -587,7 +590,7 @@
 		}
 	}
 	
-	if(ip6_socket != INVALID_SOCKET)
+	if(ip6_socket != INVALID_SOCKET && FD_ISSET(ip6_socket, fdr))
 	{
 		fromlen = sizeof(from);
 		ret = recvfrom(ip6_socket, (void *)net_message->data, net_message->maxsize, 0, (struct sockaddr *) &from, &fromlen);
@@ -604,7 +607,7 @@
 			SockadrToNetadr((struct sockaddr *) &from, net_from);
 			net_message->readcount = 0;
 		
-			if(ret == net_message->maxsize)
+			if(ret >= net_message->maxsize)
 			{
 				Com_Printf( "Oversize packet from %s\n", NET_AdrToString (*net_from) );
 				return qfalse;
@@ -615,7 +618,7 @@
 		}
 	}
 
-	if(multicast6_socket != INVALID_SOCKET && multicast6_socket != ip6_socket)
+	if(multicast6_socket != INVALID_SOCKET && multicast6_socket != ip6_socket && FD_ISSET(multicast6_socket, fdr))
 	{
 		fromlen = sizeof(from);
 		ret = recvfrom(multicast6_socket, (void *)net_message->data, net_message->maxsize, 0, (struct sockaddr *) &from, &fromlen);
@@ -632,7 +635,7 @@
 			SockadrToNetadr((struct sockaddr *) &from, net_from);
 			net_message->readcount = 0;
 		
-			if(ret == net_message->maxsize)
+			if(ret >= net_message->maxsize)
 			{
 				Com_Printf( "Oversize packet from %s\n", NET_AdrToString (*net_from) );
 				return qfalse;
@@ -1499,6 +1502,8 @@
 	modified += net_socksPassword->modified;
 	net_socksPassword->modified = qfalse;
 
+	net_dropsim = Cvar_Get("net_dropsim", "", CVAR_TEMP);
+
 	return modified ? qtrue : qfalse;
 }
 
@@ -1627,7 +1632,43 @@
 #endif
 }
 
+/*
+====================
+NET_Event
 
+Called from NET_Sleep which uses select() to determine which sockets have seen action.
+====================
+*/
+
+void NET_Event(fd_set *fdr)
+{
+	byte bufData[MAX_MSGLEN + 1];
+	netadr_t from;
+	msg_t netmsg;
+	
+	while(1)
+	{
+		MSG_Init(&netmsg, bufData, sizeof(bufData));
+
+		if(NET_GetPacket(&from, &netmsg, fdr))
+		{
+			if(net_dropsim->value > 0.0f && net_dropsim->value <= 100.0f)
+			{
+				// com_dropsim->value percent of incoming packets get dropped.
+				if(rand() < (int) (((double) RAND_MAX) / 100.0 * (double) net_dropsim->value))
+					continue;          // drop this packet
+                        }
+
+			if(com_sv_running->integer)
+				Com_RunAndTimeServerPacket(&from, &netmsg);
+			else
+				CL_PacketEvent(from, &netmsg);
+		}
+		else
+			break;
+	}
+}
+
 /*
 ====================
 NET_Sleep
@@ -1635,31 +1676,23 @@
 Sleeps msec or until something happens on the network
 ====================
 */
-void NET_Sleep( int msec ) {
+void NET_Sleep(int msec)
+{
 	struct timeval timeout;
-	fd_set	fdset;
-	int highestfd = -1;
+	fd_set fdr;
+	int highestfd = -1, retval;
 
-	if (!com_dedicated->integer)
-		return; // we're not a server, just run full speed
+	FD_ZERO(&fdr);
 
-	if (ip_socket == INVALID_SOCKET && ip6_socket == INVALID_SOCKET)
-		return;
-
-	if (msec < 0 )
-		return;
-
-	FD_ZERO(&fdset);
-
 	if(ip_socket != INVALID_SOCKET)
 	{
-		FD_SET(ip_socket, &fdset);
+		FD_SET(ip_socket, &fdr);
 
 		highestfd = ip_socket;
 	}
 	if(ip6_socket != INVALID_SOCKET)
 	{
-		FD_SET(ip6_socket, &fdset);
+		FD_SET(ip6_socket, &fdr);
 		
 		if(ip6_socket > highestfd)
 			highestfd = ip6_socket;
@@ -1667,10 +1700,33 @@
 
 	timeout.tv_sec = msec/1000;
 	timeout.tv_usec = (msec%1000)*1000;
-	select(highestfd + 1, &fdset, NULL, NULL, &timeout);
+	
+#ifdef _WIN32
+	if(highestfd < 0)
+	{
+		// windows ain't happy when select is called without valid FDs
+	
+		if(msec > 0)
+			msec--;
+		
+		SleepEx(msec, 0);
+		return;
+	}
+
+	#define TVW32_BIAS 999
+	// windows adds a whole millisecond of latency, otherwise granularity seems to be fine.
+	if(timeout.tv_usec > TVW32_BIAS)
+		timeout.tv_usec -= TVW32_BIAS;
+#endif
+
+	retval = select(highestfd + 1, &fdr, NULL, NULL, &timeout);
+	
+	if(retval < 0)
+		Com_Printf("Warning: select() syscall failed: %s\n", NET_ErrorString());
+	else if(retval > 0)
+		NET_Event(&fdr);
 }
 
-
 /*
 ====================
 NET_Restart_f

Modified: trunk/code/qcommon/qcommon.h
===================================================================
--- trunk/code/qcommon/qcommon.h	2011-01-31 22:09:47 UTC (rev 1834)
+++ trunk/code/qcommon/qcommon.h	2011-02-02 16:46:23 UTC (rev 1835)
@@ -768,13 +768,12 @@
 
 typedef enum {
 	// SE_NONE must be zero
-	SE_NONE = 0,	// evTime is still valid
-	SE_KEY,		// evValue is a key code, evValue2 is the down flag
-	SE_CHAR,	// evValue is an ascii char
-	SE_MOUSE,	// evValue and evValue2 are reletive signed x / y moves
+	SE_NONE = 0,		// evTime is still valid
+	SE_KEY,			// evValue is a key code, evValue2 is the down flag
+	SE_CHAR,		// evValue is an ascii char
+	SE_MOUSE,		// evValue and evValue2 are reletive signed x / y moves
 	SE_JOYSTICK_AXIS,	// evValue is an axis number and evValue2 is the current state (-127 to 127)
-	SE_CONSOLE,	// evPtr is a char*
-	SE_PACKET	// evPtr is a netadr_t followed by data bytes to evPtrLength
+	SE_CONSOLE		// evPtr is a char*
 } sysEventType_t;
 
 typedef struct {
@@ -807,6 +806,7 @@
 int			Com_FilterPath(char *filter, char *name, int casesensitive);
 int			Com_RealTime(qtime_t *qtime);
 qboolean	Com_SafeMode( void );
+void		Com_RunAndTimeServerPacket(netadr_t *evFrom, msg_t *buf);
 
 void		Com_StartupVariable( const char *match );
 // checks for and removes command line "+set var arg" constructs
@@ -845,7 +845,6 @@
 extern	int		time_backend;		// renderer backend time
 
 extern	int		com_frameTime;
-extern	int		com_frameMsec;
 
 extern	qboolean	com_errorEntered;
 
@@ -997,6 +996,7 @@
 void SV_Shutdown( char *finalmsg );
 void SV_Frame( int msec );
 void SV_PacketEvent( netadr_t from, msg_t *msg );
+int SV_FrameMsec(void);
 qboolean SV_GameCommand( void );
 
 
@@ -1068,7 +1068,6 @@
 void	Sys_SetErrorText( const char *text );
 
 void	Sys_SendPacket( int length, const void *data, netadr_t to );
-qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message );
 
 qboolean	Sys_StringToAdr( const char *s, netadr_t *a, netadrtype_t family );
 //Does NOT parse port numbers, only base addresses.

Modified: trunk/code/server/sv_main.c
===================================================================
--- trunk/code/server/sv_main.c	2011-01-31 22:09:47 UTC (rev 1834)
+++ trunk/code/server/sv_main.c	2011-02-02 16:46:23 UTC (rev 1835)
@@ -30,17 +30,17 @@
 server_t		sv;					// local server
 vm_t			*gvm = NULL;				// game virtual machine
 
-cvar_t	*sv_fps;				// time rate for running non-clients
+cvar_t	*sv_fps = NULL;			// time rate for running non-clients
 cvar_t	*sv_timeout;			// seconds without any message
 cvar_t	*sv_zombietime;			// seconds to sink messages after disconnect
 cvar_t	*sv_rconPassword;		// password for remote server commands
-cvar_t	*sv_privatePassword;	// password for the privateClient slots
+cvar_t	*sv_privatePassword;		// password for the privateClient slots
 cvar_t	*sv_allowDownload;
 cvar_t	*sv_maxclients;
 
 cvar_t	*sv_privateClients;		// number of clients reserved for password
 cvar_t	*sv_hostname;
-cvar_t	*sv_master[MAX_MASTER_SERVERS];		// master server ip address
+cvar_t	*sv_master[MAX_MASTER_SERVERS];	// master server ip address
 cvar_t	*sv_reconnectlimit;		// minimum seconds between connect messages
 cvar_t	*sv_showloss;			// report when usercmds are lost
 cvar_t	*sv_padPackets;			// add nop bytes to messages
@@ -1002,6 +1002,29 @@
 
 /*
 ==================
+SV_FrameMsec
+Return time in millseconds until processing of the next server frame.
+==================
+*/
+int SV_FrameMsec()
+{
+	if(sv_fps)
+	{
+		int frameMsec;
+		
+		frameMsec = 1000.0f / sv_fps->value;
+		
+		if(frameMsec < sv.timeResidual)
+			return 0;
+		else
+			return frameMsec - sv.timeResidual;
+	}
+	else
+		return 1;
+}
+
+/*
+==================
 SV_Frame
 
 Player movement occurs as a result of packet events, which
@@ -1052,13 +1075,6 @@
 
 	if (!com_dedicated->integer) SV_BotFrame (sv.time + sv.timeResidual);
 
-	if ( com_dedicated->integer && sv.timeResidual < frameMsec ) {
-		// NET_Sleep will give the OS time slices until either get a packet
-		// or time enough for a server frame has gone by
-		NET_Sleep(frameMsec - sv.timeResidual);
-		return;
-	}
-
 	// if time is about to hit the 32nd bit, kick all clients
 	// and clear sv.time, rather
 	// than checking for negative time wraparound everywhere.



More information about the quake3-commits mailing list