17 cvar_t sys_usetimegettime = {CVAR_SAVE, "sys_usetimegettime", "1", "use windows timeGetTime function (which has issues on some motherboards) for timing rather than QueryPerformanceCounter timer (which has issues on multicore/multiprocessor machines and processors which are designed to conserve power)"};
20 cvar_t sys_useclockgettime = {CVAR_SAVE, "sys_useclockgettime", "0", "use POSIX clock_gettime function (which has issues if the system clock speed is far off, as it can't get fixed by NTP) for timing rather than gettimeofday (which has issues if the system time is stepped by ntpdate, or apparently on some Xen installations)"};
26 // =======================================================================
28 // =======================================================================
29 void Sys_Shutdown (void)
32 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
37 void Sys_Error (const char *error, ...)
40 char string[MAX_INPUTLINE];
42 // change stdin to non blocking
44 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
47 va_start (argptr,error);
48 dpvsnprintf (string, sizeof (string), error, argptr);
51 Con_Printf ("Quake Error: %s\n", string);
57 void Sys_PrintToTerminal(const char *text)
60 // BUG: for some reason, NDELAY also affects stdout (1) when used on stdin (0).
61 int origflags = fcntl (1, F_GETFL, 0);
62 fcntl (1, F_SETFL, origflags & ~FNDELAY);
68 int written = (int)write(1, text, (int)strlen(text));
70 break; // sorry, I cannot do anything about this error - without an output
74 fcntl (1, F_SETFL, origflags);
76 //fprintf(stdout, "%s", text);
79 double Sys_DoubleTime (void)
81 static int first = true;
82 static double oldtime = 0.0, curtime = 0.0;
86 // LordHavoc: note to people modifying this code, DWORD is specifically defined as an unsigned 32bit number, therefore the 65536.0 * 65536.0 is fine.
87 if (sys_usetimegettime.integer)
89 static int firsttimegettime = true;
92 // Windows 95/98/ME/NT/2000/XP
94 // reasonable accuracy (millisecond)
96 // wraps around every 47 days or so (but this is non-fatal to us, odd times are rejected, only causes a one frame stutter)
98 // make sure the timer is high precision, otherwise different versions of windows have varying accuracy
102 firsttimegettime = false;
105 newtime = (double) timeGetTime () / 1000.0;
109 // QueryPerformanceCounter
111 // Windows 95/98/ME/NT/2000/XP
113 // very accurate (CPU cycles)
115 // does not necessarily match realtime too well (tends to get faster and faster in win98)
116 // wraps around occasionally on some platforms (depends on CPU speed and probably other unknown factors)
118 LARGE_INTEGER PerformanceFreq;
119 LARGE_INTEGER PerformanceCount;
121 if (!QueryPerformanceFrequency (&PerformanceFreq))
123 Con_Printf ("No hardware timer available\n");
124 // fall back to timeGetTime
125 Cvar_SetValueQuick(&sys_usetimegettime, true);
126 return Sys_DoubleTime();
128 QueryPerformanceCounter (&PerformanceCount);
131 timescale = 1.0 / ((double) PerformanceFreq.u.LowPart + (double) PerformanceFreq.u.HighPart * 65536.0 * 65536.0);
132 newtime = ((double) PerformanceCount.u.LowPart + (double) PerformanceCount.u.HighPart * 65536.0 * 65536.0) * timescale;
134 timescale = 1.0 / ((double) PerformanceFreq.LowPart + (double) PerformanceFreq.HighPart * 65536.0 * 65536.0);
135 newtime = ((double) PerformanceCount.LowPart + (double) PerformanceCount.HighPart * 65536.0 * 65536.0) * timescale;
140 if (sys_useclockgettime.integer)
144 clock_gettime(CLOCK_HIGHRES, &ts);
146 clock_gettime(CLOCK_MONOTONIC, &ts);
148 newtime = (double) ts.tv_sec + ts.tv_nsec / 1000000000.0;
154 gettimeofday(&tp, NULL);
155 newtime = (double) tp.tv_sec + tp.tv_usec / 1000000.0;
165 if (newtime < oldtime)
167 // warn if it's significant
168 if (newtime - oldtime < -0.01)
169 Con_Printf("Sys_DoubleTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime);
171 else if (newtime > oldtime + 1800)
173 Con_Printf("Sys_DoubleTime: time stepped forward (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime);
176 curtime += newtime - oldtime;
182 char *Sys_ConsoleInput(void)
184 if (cls.state == ca_dedicated)
186 static char text[MAX_INPUTLINE];
187 static unsigned int len = 0;
213 if (len < sizeof (text) - 1)
222 struct timeval timeout;
224 FD_SET(0, &fdset); // stdin
227 if (select (1, &fdset, NULL, NULL, &timeout) != -1 && FD_ISSET(0, &fdset))
229 len = read (0, text, sizeof(text));
232 // rip off the \n and terminate
242 void Sys_Sleep(int microseconds)
245 Sleep(microseconds / 1000);
247 usleep(microseconds);
251 char *Sys_GetClipboardData (void)
256 void Sys_InitConsole (void)
260 void Sys_Init_Commands (void)
263 Cvar_RegisterVariable(&sys_usetimegettime);
266 Cvar_RegisterVariable(&sys_useclockgettime);
271 int main (int argc, char **argv)
273 signal(SIGFPE, SIG_IGN);
276 com_argv = (const char **)argv;
279 fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);