int main (int argc, char **argv) { double time, oldtime, newtime; #ifdef PARANOID signal(SIGFPE, floating_point_exception_handler); #else signal(SIGFPE, SIG_IGN); #endif #ifdef hpux // makes it possible to access unaligned pointers (e.g. inside structures) // must be linked with libhpp.a to work (add -lhppa to LDFLAGS) allow_unaligned_data_access(); #endif // we need to check for -noconinput and -nostdout // before Host_Init is called COM_InitArgv (argc, argv); noconinput = COM_CheckParm("-noconinput"); if (!noconinput) fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | O_NDELAY); if (COM_CheckParm("-nostdout")) nostdout = 1; #if id386 Sys_SetFPCW(); #endif Host_Init (argc, argv, 16*1024*1024); oldtime = Sys_DoubleTime (); while (1) { if (dedicated) NET_Sleep (10); // find time spent rendering last frame newtime = Sys_DoubleTime (); time = newtime - oldtime; Host_Frame(time); oldtime = newtime; } return 0; }
/* ============= main ============= */ int main (int argc, char *argv[]) { double time1, oldtime, newtime; // Without signal(SIGPIPE, SIG_IGN); MVDSV crashes on *nix when qtvproxy will be disconnect. signal(SIGPIPE, SIG_IGN); COM_InitArgv (argc, argv); SV_System_Init(); // daemonize and so... Host_Init(argc, argv, DEFAULT_MEM_SIZE); // run one frame immediately for first heartbeat SV_Frame (0.1); // main loop oldtime = Sys_DoubleTime () - 0.1; while (1) { // select on the net socket and stdin // the only reason we have a timeout at all is so that if the last // connected client times out, the message would not otherwise // be printed until the next event. stdin_ready = NET_Sleep ((int)sys_select_timeout.value / 1000, do_stdin); // find time passed since last cycle newtime = Sys_DoubleTime (); time1 = newtime - oldtime; oldtime = newtime; curtime = newtime; SV_Frame (time1); // extrasleep is just a way to generate a f****d up connection on purpose if ((int)sys_extrasleep.value) usleep ((unsigned long)sys_extrasleep.value); } return 0; }
/* ================== SV_Frame Player movement occurs as a result of packet events, which happen before SV_Frame is called ================== */ void SV_Frame( int msec ) { int frameMsec; int startTime; // the menu kills the server with this cvar if ( sv_killserver->integer ) { SV_Shutdown ("Server was killed"); Cvar_Set( "sv_killserver", "0" ); return; } if (!com_sv_running->integer) { if(com_dedicated->integer) { // Block indefinitely until something interesting happens // on STDIN. NET_Sleep(-1); } return; } // allow pause if only the local client is connected if ( SV_CheckPaused() ) { return; } // if it isn't time for the next frame, do nothing if ( sv_fps->integer < 1 ) { Cvar_Set( "sv_fps", "10" ); } frameMsec = 1000 / sv_fps->integer * com_timescale->value; // don't let it scale below 1ms if(frameMsec < 1) { Cvar_Set("timescale", va("%f", sv_fps->integer / 1000.0f)); frameMsec = 1; } sv.timeResidual += msec; 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. // 2giga-milliseconds = 23 days, so it won't be too often if ( svs.time > 0x70000000 ) { SV_Shutdown( "Restarting server due to time wrapping" ); Cbuf_AddText( va( "map %s\n", Cvar_VariableString( "mapname" ) ) ); return; } // this can happen considerably earlier when lots of clients play and the map doesn't change if ( svs.nextSnapshotEntities >= 0x7FFFFFFE - svs.numSnapshotEntities ) { SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" ); Cbuf_AddText( va( "map %s\n", Cvar_VariableString( "mapname" ) ) ); return; } if( sv.restartTime && sv.time >= sv.restartTime ) { sv.restartTime = 0; Cbuf_AddText( "map_restart 0\n" ); return; } // update infostrings if anything has been changed if ( cvar_modifiedFlags & CVAR_SERVERINFO ) { SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) ); cvar_modifiedFlags &= ~CVAR_SERVERINFO; } if ( cvar_modifiedFlags & CVAR_SYSTEMINFO ) { SV_SetConfigstring( CS_SYSTEMINFO, Cvar_InfoString_Big( CVAR_SYSTEMINFO ) ); cvar_modifiedFlags &= ~CVAR_SYSTEMINFO; } if ( com_speeds->integer ) { startTime = Sys_Milliseconds (); } else { startTime = 0; // quite a compiler warning } // update ping based on the all received frames SV_CalcPings(); if (com_dedicated->integer) SV_BotFrame (sv.time); // run the game simulation in chunks while ( sv.timeResidual >= frameMsec ) { sv.timeResidual -= frameMsec; svs.time += frameMsec; sv.time += frameMsec; // let everything in the world think and move VM_Call (gvm, GAME_RUN_FRAME, sv.time); } if ( com_speeds->integer ) { time_game = Sys_Milliseconds () - startTime; } // check timeouts SV_CheckTimeouts(); // check user info buffer thingy SV_CheckClientUserinfoTimer(); // send messages back to the clients SV_SendClientMessages(); // send a heartbeat to the master if needed SV_MasterHeartbeat(); }
/* ================== SV_Frame Player movement occurs as a result of packet events, which happen before SV_Frame is called ================== */ void SV_Frame( int msec ) { int frameMsec; int startTime; #if !defined RTCW_SP char mapname[MAX_QPATH]; #endif // RTCW_XX #if defined RTCW_ET int frameStartTime = 0, frameEndTime; #endif // RTCW_XX // the menu kills the server with this cvar if ( sv_killserver->integer ) { SV_Shutdown( "Server was killed.\n" ); Cvar_Set( "sv_killserver", "0" ); return; } if ( !com_sv_running->integer ) { return; } // allow pause if only the local client is connected if ( SV_CheckPaused() ) { return; } #if defined RTCW_ET if ( com_dedicated->integer ) { frameStartTime = Sys_Milliseconds(); } #endif // RTCW_XX // if it isn't time for the next frame, do nothing if ( sv_fps->integer < 1 ) { Cvar_Set( "sv_fps", "10" ); } frameMsec = 1000 / sv_fps->integer ; sv.timeResidual += msec; if ( !com_dedicated->integer ) { SV_BotFrame( svs.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. // 2giga-milliseconds = 23 days, so it won't be too often if ( svs.time > 0x70000000 ) { #if defined RTCW_SP SV_Shutdown( "Restarting server due to time wrapping" ); Cbuf_AddText( "vstr nextmap\n" ); #else Q_strncpyz( mapname, sv_mapname->string, MAX_QPATH ); SV_Shutdown( "Restarting server due to time wrapping" ); // TTimo // show_bug.cgi?id=388 // there won't be a map_restart if you have shut down the server // since it doesn't restart a non-running server // instead, re-run the current map Cbuf_AddText( va( "map %s\n", mapname ) ); #endif // RTCW_XX return; } // this can happen considerably earlier when lots of clients play and the map doesn't change if ( svs.nextSnapshotEntities >= 0x7FFFFFFE - svs.numSnapshotEntities ) { #if defined RTCW_SP SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" ); Cbuf_AddText( "vstr nextmap\n" ); #else Q_strncpyz( mapname, sv_mapname->string, MAX_QPATH ); SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" ); // TTimo see above Cbuf_AddText( va( "map %s\n", mapname ) ); #endif // RTCW_XX return; } if ( sv.restartTime && svs.time >= sv.restartTime ) { sv.restartTime = 0; Cbuf_AddText( "map_restart 0\n" ); return; } // update infostrings if anything has been changed if ( cvar_modifiedFlags & CVAR_SERVERINFO ) { #if !defined RTCW_ET SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) ); #else SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO | CVAR_SERVERINFO_NOUPDATE ) ); #endif // RTCW_XX cvar_modifiedFlags &= ~CVAR_SERVERINFO; } #if defined RTCW_ET if ( cvar_modifiedFlags & CVAR_SERVERINFO_NOUPDATE ) { SV_SetConfigstringNoUpdate( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO | CVAR_SERVERINFO_NOUPDATE ) ); cvar_modifiedFlags &= ~CVAR_SERVERINFO_NOUPDATE; } #endif // RTCW_XX if ( cvar_modifiedFlags & CVAR_SYSTEMINFO ) { SV_SetConfigstring( CS_SYSTEMINFO, Cvar_InfoString_Big( CVAR_SYSTEMINFO ) ); cvar_modifiedFlags &= ~CVAR_SYSTEMINFO; } #if !defined RTCW_SP // NERVE - SMF if ( cvar_modifiedFlags & CVAR_WOLFINFO ) { SV_SetConfigstring( CS_WOLFINFO, Cvar_InfoString( CVAR_WOLFINFO ) ); cvar_modifiedFlags &= ~CVAR_WOLFINFO; } #endif // RTCW_XX if ( com_speeds->integer ) { startTime = Sys_Milliseconds(); } else { startTime = 0; // quite a compiler warning } // update ping based on the all received frames SV_CalcPings(); if ( com_dedicated->integer ) { SV_BotFrame( svs.time ); } // run the game simulation in chunks while ( sv.timeResidual >= frameMsec ) { sv.timeResidual -= frameMsec; svs.time += frameMsec; // let everything in the world think and move #if !defined RTCW_MP || (defined RTCW_MP && !UPDATE_SERVER) VM_Call( gvm, GAME_RUN_FRAME, svs.time ); #endif // RTCW_XX } if ( com_speeds->integer ) { time_game = Sys_Milliseconds() - startTime; } // check timeouts SV_CheckTimeouts(); // send messages back to the clients SV_SendClientMessages(); // send a heartbeat to the master if needed #if defined RTCW_SP SV_MasterHeartbeat(); #else SV_MasterHeartbeat( HEARTBEAT_GAME ); #endif // RTCW_XX #if defined RTCW_ET if ( com_dedicated->integer ) { frameEndTime = Sys_Milliseconds(); svs.totalFrameTime += ( frameEndTime - frameStartTime ); svs.currentFrameIndex++; //if( svs.currentFrameIndex % 50 == 0 ) // Com_Printf( "currentFrameIndex: %i\n", svs.currentFrameIndex ); if ( svs.currentFrameIndex == SERVER_PERFORMANCECOUNTER_FRAMES ) { int averageFrameTime; averageFrameTime = svs.totalFrameTime / SERVER_PERFORMANCECOUNTER_FRAMES; svs.sampleTimes[svs.currentSampleIndex % SERVER_PERFORMANCECOUNTER_SAMPLES] = averageFrameTime; svs.currentSampleIndex++; if ( svs.currentSampleIndex > SERVER_PERFORMANCECOUNTER_SAMPLES ) { int totalTime, i; totalTime = 0; for ( i = 0; i < SERVER_PERFORMANCECOUNTER_SAMPLES; i++ ) { totalTime += svs.sampleTimes[i]; } if ( !totalTime ) { totalTime = 1; } averageFrameTime = totalTime / SERVER_PERFORMANCECOUNTER_SAMPLES; svs.serverLoad = ( averageFrameTime / (float)frameMsec ) * 100; } //Com_Printf( "serverload: %i (%i/%i)\n", svs.serverLoad, averageFrameTime, frameMsec ); svs.totalFrameTime = 0; svs.currentFrameIndex = 0; } } else { svs.serverLoad = -1; } #endif // RTCW_XX }
/* ================== SV_Frame Player movement occurs as a result of packet events, which happen before SV_Frame is called ================== */ void SV_Frame( int msec ) { int frameMsec; int startTime; char mapname[MAX_QPATH]; // the menu kills the server with this cvar if ( sv_killserver->integer ) { SV_Shutdown( "Server was killed.\n" ); Cvar_Set( "sv_killserver", "0" ); return; } if ( !com_sv_running->integer ) { return; } // allow pause if only the local client is connected if ( SV_CheckPaused() ) { return; } // if it isn't time for the next frame, do nothing if ( sv_fps->integer < 1 ) { Cvar_Set( "sv_fps", "10" ); } frameMsec = 1000 / sv_fps->integer ; sv.timeResidual += msec; if ( !com_dedicated->integer ) { SV_BotFrame( svs.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. // 2giga-milliseconds = 23 days, so it won't be too often if ( svs.time > 0x70000000 ) { Q_strncpyz( mapname, sv_mapname->string, MAX_QPATH ); SV_Shutdown( "Restarting server due to time wrapping" ); // TTimo // show_bug.cgi?id=388 // there won't be a map_restart if you have shut down the server // since it doesn't restart a non-running server // instead, re-run the current map Cbuf_AddText( va( "map %s\n", mapname ) ); return; } // this can happen considerably earlier when lots of clients play and the map doesn't change if ( svs.nextSnapshotEntities >= 0x7FFFFFFE - svs.numSnapshotEntities ) { Q_strncpyz( mapname, sv_mapname->string, MAX_QPATH ); SV_Shutdown( "Restarting server due to numSnapshotEntities wrapping" ); // TTimo see above Cbuf_AddText( va( "map %s\n", mapname ) ); return; } if ( sv.restartTime && svs.time >= sv.restartTime ) { sv.restartTime = 0; Cbuf_AddText( "map_restart 0\n" ); return; } // update infostrings if anything has been changed if ( cvar_modifiedFlags & CVAR_SERVERINFO ) { SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO ) ); cvar_modifiedFlags &= ~CVAR_SERVERINFO; } if ( cvar_modifiedFlags & CVAR_SYSTEMINFO ) { SV_SetConfigstring( CS_SYSTEMINFO, Cvar_InfoString_Big( CVAR_SYSTEMINFO ) ); cvar_modifiedFlags &= ~CVAR_SYSTEMINFO; } // NERVE - SMF if ( cvar_modifiedFlags & CVAR_WOLFINFO ) { SV_SetConfigstring( CS_WOLFINFO, Cvar_InfoString( CVAR_WOLFINFO ) ); cvar_modifiedFlags &= ~CVAR_WOLFINFO; } if ( com_speeds->integer ) { startTime = Sys_Milliseconds(); } else { startTime = 0; // quite a compiler warning } // update ping based on the all received frames SV_CalcPings(); if ( com_dedicated->integer ) { SV_BotFrame( svs.time ); } // run the game simulation in chunks while ( sv.timeResidual >= frameMsec ) { sv.timeResidual -= frameMsec; svs.time += frameMsec; // let everything in the world think and move #ifndef UPDATE_SERVER VM_Call( gvm, GAME_RUN_FRAME, svs.time ); #endif } if ( com_speeds->integer ) { time_game = Sys_Milliseconds() - startTime; } // check timeouts SV_CheckTimeouts(); // send messages back to the clients SV_SendClientMessages(); // send a heartbeat to the master if needed SV_MasterHeartbeat( HEARTBEAT_GAME ); }
/* ================= 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 }
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { static MSG msg; static double newtime, time, oldtime; register int sleep_msec; static qbool disable_gpf = false; ParseCommandLine(lpCmdLine); COM_InitArgv (argc, argv); // create main window if (!CreateMainWindow(hInstance, nCmdShow)) return 1; if (COM_CheckParm("-noerrormsgbox")) disable_gpf = true; if (COM_CheckParm ("-d")) { isdaemon = disable_gpf = true; //close(0); close(1); close(2); } if (disable_gpf) { DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX); SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX); } Host_Init(argc, argv, DEFAULT_MEM_SIZE); // if stared miminize update notify icon message (with correct port) if (minimized) UpdateNotifyIconMessage(va(SERVER_NAME ":%d", NET_UDPSVPort())); // run one frame immediately for first heartbeat SV_Frame (0.1); // // main loop // oldtime = Sys_DoubleTime () - 0.1; while(1) { // get messeges sent to windows if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) { if( !GetMessage( &msg, NULL, 0, 0 ) ) break; if(!IsDialogMessage(DlgHwnd, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } CheckIdle(); // server frame sleep_msec = (int)sys_sleep.value; if (sleep_msec > 0) { if (sleep_msec > 13) sleep_msec = 13; Sleep (sleep_msec); } // select on the net socket and stdin // the only reason we have a timeout at all is so that if the last // connected client times out, the message would not otherwise // be printed until the next event. if (!sys_simulation.value) { NET_Sleep((int)sys_select_timeout.value / 1000, false); } // find time passed since last cycle newtime = Sys_DoubleTime (); time = newtime - oldtime; oldtime = newtime; curtime = newtime; SV_Frame (time); } Sys_Exit(msg.wParam); return msg.wParam; }
/* * SV_RunGameFrame */ static qboolean SV_RunGameFrame( int msec ) { static unsigned int accTime = 0; qboolean refreshSnapshot; qboolean refreshGameModule; qboolean sentFragments; accTime += msec; refreshSnapshot = qfalse; refreshGameModule = qfalse; sentFragments = SV_SendClientsFragments(); // see if it's time to run a new game frame if( accTime >= WORLDFRAMETIME ) refreshGameModule = qtrue; // see if it's time for a new snapshot if( !sentFragments && svs.gametime >= sv.nextSnapTime ) { refreshSnapshot = qtrue; refreshGameModule = qtrue; } // if there aren't pending packets to be sent, we can sleep if( dedicated->integer && !sentFragments && !refreshSnapshot ) { int sleeptime = min( WORLDFRAMETIME - ( accTime + 1 ), sv.nextSnapTime - ( svs.gametime + 1 ) ); if( sleeptime > 0 ) { socket_t *sockets [] = { &svs.socket_udp, &svs.socket_udp6 }; socket_t *opened_sockets [sizeof( sockets ) / sizeof( sockets[0] ) + 1 ]; size_t sock_ind, open_ind; // Pass only the opened sockets to the sleep function open_ind = 0; for ( sock_ind = 0; sock_ind < sizeof( sockets ) / sizeof( sockets[0] ); sock_ind++) { socket_t *sock = sockets[sock_ind]; if ( sock->open ) { opened_sockets[open_ind] = sock; open_ind++; } } opened_sockets[open_ind] = NULL; NET_Sleep( sleeptime, opened_sockets ); } } if( refreshGameModule ) { unsigned int moduleTime; // update ping based on the last known frame from all clients SV_CalcPings(); if( accTime >= WORLDFRAMETIME ) { moduleTime = WORLDFRAMETIME; accTime -= WORLDFRAMETIME; if( accTime >= WORLDFRAMETIME ) // don't let it accumulate more than 1 frame accTime = WORLDFRAMETIME - 1; } else { moduleTime = accTime; accTime = 0; } if( host_speeds->integer ) time_before_game = Sys_Milliseconds(); ge->RunFrame( moduleTime, svs.gametime ); if( host_speeds->integer ) time_after_game = Sys_Milliseconds(); } // if we don't have to send a snapshot we are done here if( refreshSnapshot ) { int extraSnapTime; // set up for sending a snapshot sv.framenum++; ge->SnapFrame(); // set time for next snapshot extraSnapTime = (int)( svs.gametime - sv.nextSnapTime ); if( extraSnapTime > svc.snapFrameTime * 0.5 ) // don't let too much time be accumulated extraSnapTime = svc.snapFrameTime * 0.5; sv.nextSnapTime = svs.gametime + ( svc.snapFrameTime - extraSnapTime ); return qtrue; } return qfalse; }
int main(int argc, char* argv[]){ int len, i; char *cmdline; eventQue = (sysEvent_t*)evenQue_ADDR; // go back to real user for config loads Sys_LoadDifferentImage(argv); seteuid(getuid()); Sys_PlatformInit( ); Sys_ThreadInit(); Sys_ThreadMain(); Com_InitParse(); // Cvar_Init(); Sys_ParseArgs(argc, argv); // merge the command line, this is kinda silly for ( len = 1, i = 1; i < argc; i++ ) len += strlen( argv[i] ) + 1; cmdline = malloc( len ); *cmdline = 0; for ( i = 1; i < argc; i++ ){ if ( i > 1 ) { strcat( cmdline, " " ); } strcat( cmdline, argv[i] ); } // bk000306 - clear eventqueue memset( &eventQue[0], 0, MAX_QUED_EVENTS * sizeof( sysEvent_t ) ); Sys_Milliseconds(); // addrtest(); Com_Init( cmdline ); CON_Init(); signal( SIGILL, Sys_SigHandler ); // signal( SIGFPE, Sys_SigHandler ); // signal( SIGSEGV, Sys_SigHandler ); signal( SIGTERM, Sys_SigHandler ); signal( SIGINT, Sys_SigHandler ); fcntl( 0, F_SETFL, fcntl( 0, F_GETFL, 0 ) | FNDELAY ); if(!PbServerInitialize()){ Com_Printf("Unable to initialize PunkBuster. PunkBuster is disabled.\n"); } // GetVirtualFunctionArray(); // Com_Quit_f(); while ( 1 ) { static int fpu_word = _FPU_DEFAULT; _FPU_SETCW( fpu_word ); NET_Sleep(5); Com_Frame(); PbServerProcessEvents(); } }