-Removed Sys_Quit and added Sys_Shutdown which will be called by Host_Shutdown.
[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         Host_Shutdown ();
50         exit (1);
51 }
52
53 void Sys_PrintToTerminal(const char *text)
54 {
55         printf("%s", text);
56 }
57
58 double Sys_DoubleTime (void)
59 {
60         static int first = true;
61         static double oldtime = 0.0, curtime = 0.0;
62         double newtime;
63 #ifdef WIN32
64         // LordHavoc: note to people modifying this code, DWORD is specifically defined as an unsigned 32bit number, therefore the 65536.0 * 65536.0 is fine.
65         if (!sys_usetimegettime.integer)
66         {
67                 // QueryPerformanceCounter
68                 // platform:
69                 // Windows 95/98/ME/NT/2000/XP
70                 // features:
71                 // very accurate (CPU cycles)
72                 // known issues:
73                 // does not necessarily match realtime too well (tends to get faster and faster in win98)
74                 // wraps around occasionally on some platforms (depends on CPU speed and probably other unknown factors)
75                 double timescale;
76                 LARGE_INTEGER PerformanceFreq;
77                 LARGE_INTEGER PerformanceCount;
78
79                 if (!QueryPerformanceFrequency (&PerformanceFreq))
80                         Sys_Error ("No hardware timer available");
81                 QueryPerformanceCounter (&PerformanceCount);
82
83                 #ifdef __BORLANDC__
84                 timescale = 1.0 / ((double) PerformanceFreq.u.LowPart + (double) PerformanceFreq.u.HighPart * 65536.0 * 65536.0);
85                 newtime = ((double) PerformanceCount.u.LowPart + (double) PerformanceCount.u.HighPart * 65536.0 * 65536.0) * timescale;
86                 #else
87                 timescale = 1.0 / ((double) PerformanceFreq.LowPart + (double) PerformanceFreq.HighPart * 65536.0 * 65536.0);
88                 newtime = ((double) PerformanceCount.LowPart + (double) PerformanceCount.HighPart * 65536.0 * 65536.0) * timescale;
89                 #endif
90         } else
91 #endif
92         newtime = (double) SDL_GetTicks() / 1000.0;
93
94
95         if (first)
96         {
97                 first = false;
98                 oldtime = newtime;
99         }
100
101         if (newtime < oldtime)
102         {
103                 // warn if it's significant
104                 if (newtime - oldtime < -0.01)
105                         Con_Printf("Sys_DoubleTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime);
106         }
107         else
108                 curtime += newtime - oldtime;
109         oldtime = newtime;
110
111         return curtime;
112 }
113
114 char *Sys_ConsoleInput(void)
115 {
116         if (cls.state == ca_dedicated)
117         {
118                 static char text[256];
119                 int len = 0;
120 #ifdef WIN32
121                 int c;
122
123                 // read a line out
124                 while (_kbhit ())
125                 {
126                         c = _getch ();
127                         putch (c);
128                         if (c == '\r')
129                         {
130                                 text[len] = 0;
131                                 putch ('\n');
132                                 len = 0;
133                                 return text;
134                         }
135                         if (c == 8)
136                         {
137                                 if (len)
138                                 {
139                                         putch (' ');
140                                         putch (c);
141                                         len--;
142                                         text[len] = 0;
143                                 }
144                                 continue;
145                         }
146                         text[len] = c;
147                         len++;
148                         text[len] = 0;
149                         if (len == sizeof (text))
150                                 len = 0;
151                 }
152 #else
153                 fd_set fdset;
154                 struct timeval timeout;
155                 FD_ZERO(&fdset);
156                 FD_SET(0, &fdset); // stdin
157                 timeout.tv_sec = 0;
158                 timeout.tv_usec = 0;
159                 if (select (1, &fdset, NULL, NULL, &timeout) != -1 && FD_ISSET(0, &fdset))
160                 {
161                         len = read (0, text, sizeof(text));
162                         if (len >= 1)
163                         {
164                                 // rip off the \n and terminate
165                                 text[len-1] = 0;
166                                 return text;
167                         }
168                 }
169 #endif
170         }
171         return NULL;
172 }
173
174 void Sys_Sleep(int milliseconds)
175 {
176         if (milliseconds < 1)
177                 milliseconds = 1;
178         SDL_Delay(milliseconds);
179 }
180
181 int SDL_main (int argc, char *argv[])
182 {
183         double frameoldtime, framenewtime;
184
185         signal(SIGFPE, SIG_IGN);
186
187         com_argc = argc;
188         com_argv = argv;
189
190 #ifndef WIN32
191         fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
192 #endif
193
194         Sys_Shared_EarlyInit();
195
196 #ifdef WIN32
197         Cvar_RegisterVariable(&sys_usetimegettime);
198 #endif
199
200         Host_Init();
201
202         Sys_Shared_LateInit();
203
204         frameoldtime = Sys_DoubleTime () - 0.1;
205         while (1)
206         {
207                 // find time spent rendering last frame
208                 framenewtime = Sys_DoubleTime ();
209
210                 Host_Frame (framenewtime - frameoldtime);
211
212                 frameoldtime = framenewtime;
213         }
214         return 0;
215 }