Disabled vsync when doing a timedemo.
[divverent/darkplaces.git] / sys_sdl.c
1
2 #ifdef WIN32
3 #include "conio.h"
4 #else
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <sys/time.h>
8 #endif
9
10 #include <signal.h>
11
12 #include "quakedef.h"
13
14 #include <SDL.h>
15
16 #ifdef WIN32
17 cvar_t sys_usetimegettime = {CVAR_SAVE, "sys_usetimegettime", "1"};
18 #endif
19
20 // =======================================================================
21 // General routines
22 // =======================================================================
23
24 void Sys_Shutdown (void)
25 {
26 #ifndef WIN32
27         fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
28 #endif
29         fflush(stdout);
30         SDL_Quit();
31 }
32         
33
34 void Sys_Error (const char *error, ...)
35 {
36         va_list argptr;
37         char string[1024];
38
39 // change stdin to non blocking
40 #ifndef WIN32
41         fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
42 #endif
43
44         va_start (argptr,error);
45         vsnprintf (string, sizeof (string), error, argptr);
46         va_end (argptr);
47         fprintf(stderr, "Error: %s\n", string);
48
49         Con_Print ("Quake Error: ");
50         Con_Print (string);
51         Con_Print ("\n");
52
53         Host_Shutdown ();
54         exit (1);
55 }
56
57 void Sys_PrintToTerminal(const char *text)
58 {
59         printf("%s", text);
60 }
61
62 double Sys_DoubleTime (void)
63 {
64         static int first = true;
65         static double oldtime = 0.0, curtime = 0.0;
66         double newtime;
67 #ifdef WIN32
68         // LordHavoc: note to people modifying this code, DWORD is specifically defined as an unsigned 32bit number, therefore the 65536.0 * 65536.0 is fine.
69         if (!sys_usetimegettime.integer)
70         {
71                 // QueryPerformanceCounter
72                 // platform:
73                 // Windows 95/98/ME/NT/2000/XP
74                 // features:
75                 // very accurate (CPU cycles)
76                 // known issues:
77                 // does not necessarily match realtime too well (tends to get faster and faster in win98)
78                 // wraps around occasionally on some platforms (depends on CPU speed and probably other unknown factors)
79                 double timescale;
80                 LARGE_INTEGER PerformanceFreq;
81                 LARGE_INTEGER PerformanceCount;
82
83                 if (!QueryPerformanceFrequency (&PerformanceFreq))
84                         Sys_Error ("No hardware timer available");
85                 QueryPerformanceCounter (&PerformanceCount);
86
87                 #ifdef __BORLANDC__
88                 timescale = 1.0 / ((double) PerformanceFreq.u.LowPart + (double) PerformanceFreq.u.HighPart * 65536.0 * 65536.0);
89                 newtime = ((double) PerformanceCount.u.LowPart + (double) PerformanceCount.u.HighPart * 65536.0 * 65536.0) * timescale;
90                 #else
91                 timescale = 1.0 / ((double) PerformanceFreq.LowPart + (double) PerformanceFreq.HighPart * 65536.0 * 65536.0);
92                 newtime = ((double) PerformanceCount.LowPart + (double) PerformanceCount.HighPart * 65536.0 * 65536.0) * timescale;
93                 #endif
94         } else
95 #endif
96         newtime = (double) SDL_GetTicks() / 1000.0;
97
98
99         if (first)
100         {
101                 first = false;
102                 oldtime = newtime;
103         }
104
105         if (newtime < oldtime)
106         {
107                 // warn if it's significant
108                 if (newtime - oldtime < -0.01)
109                         Con_Printf("Sys_DoubleTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime);
110         }
111         else
112                 curtime += newtime - oldtime;
113         oldtime = newtime;
114
115         return curtime;
116 }
117
118 char *Sys_ConsoleInput(void)
119 {
120         if (cls.state == ca_dedicated)
121         {
122                 static char text[256];
123                 int len = 0;
124 #ifdef WIN32
125                 int c;
126
127                 // read a line out
128                 while (_kbhit ())
129                 {
130                         c = _getch ();
131                         putch (c);
132                         if (c == '\r')
133                         {
134                                 text[len] = 0;
135                                 putch ('\n');
136                                 len = 0;
137                                 return text;
138                         }
139                         if (c == 8)
140                         {
141                                 if (len)
142                                 {
143                                         putch (' ');
144                                         putch (c);
145                                         len--;
146                                         text[len] = 0;
147                                 }
148                                 continue;
149                         }
150                         text[len] = c;
151                         len++;
152                         text[len] = 0;
153                         if (len == sizeof (text))
154                                 len = 0;
155                 }
156 #else
157                 fd_set fdset;
158                 struct timeval timeout;
159                 FD_ZERO(&fdset);
160                 FD_SET(0, &fdset); // stdin
161                 timeout.tv_sec = 0;
162                 timeout.tv_usec = 0;
163                 if (select (1, &fdset, NULL, NULL, &timeout) != -1 && FD_ISSET(0, &fdset))
164                 {
165                         len = read (0, text, sizeof(text));
166                         if (len >= 1)
167                         {
168                                 // rip off the \n and terminate
169                                 text[len-1] = 0;
170                                 return text;
171                         }
172                 }
173 #endif
174         }
175         return NULL;
176 }
177
178 void Sys_Sleep(int milliseconds)
179 {
180         if (milliseconds < 1)
181                 milliseconds = 1;
182         SDL_Delay(milliseconds);
183 }
184
185 char *Sys_GetClipboardData (void)
186 {
187 #ifdef WIN32
188         char *data = NULL;
189         char *cliptext;
190
191         if (OpenClipboard (NULL) != 0)
192         {
193                 HANDLE hClipboardData;
194
195                 if ((hClipboardData = GetClipboardData (CF_TEXT)) != 0)
196                 {
197                         if ((cliptext = GlobalLock (hClipboardData)) != 0) 
198                         {
199                                 data = malloc (GlobalSize(hClipboardData)+1);
200                                 strcpy (data, cliptext);
201                                 GlobalUnlock (hClipboardData);
202                         }
203                 }
204                 CloseClipboard ();
205         }
206         return data;
207 #else
208         return NULL;
209 #endif
210 }
211
212 int main (int argc, char *argv[])
213 {
214         double frameoldtime, framenewtime;
215
216         signal(SIGFPE, SIG_IGN);
217
218         com_argc = argc;
219         com_argv = (const char **)argv;
220
221 #ifndef WIN32
222         fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
223 #endif
224
225         Sys_Shared_EarlyInit();
226
227 #ifdef WIN32
228         Cvar_RegisterVariable(&sys_usetimegettime);
229 #endif
230
231         Host_Init();
232
233         Sys_Shared_LateInit();
234
235         frameoldtime = Sys_DoubleTime () - 0.1;
236         while (1)
237         {
238                 // find time spent rendering last frame
239                 framenewtime = Sys_DoubleTime ();
240
241                 Host_Frame (framenewtime - frameoldtime);
242
243                 frameoldtime = framenewtime;
244         }
245         return 0;
246 }