Elric's changes:
[divverent/darkplaces.git] / sys_linux.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdarg.h>
4
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <unistd.h>
8 #include <fcntl.h>
9
10 #include <signal.h>
11 #include <limits.h>
12 #include <sys/ipc.h>
13 #include <sys/shm.h>
14 #include <sys/time.h>
15 #include <sys/wait.h>
16 #include <sys/mman.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <errno.h>
20 #include <time.h>
21
22 #include <dlfcn.h>
23
24 #include "quakedef.h"
25
26 /*
27 ===============================================================================
28
29 DLL MANAGEMENT
30
31 ===============================================================================
32 */
33
34 dllhandle_t Sys_LoadLibrary (const char* name)
35 {
36         return dlopen (name, RTLD_LAZY);
37 }
38
39 void Sys_UnloadLibrary (dllhandle_t handle)
40 {
41         dlclose (handle);
42 }
43
44 void* Sys_GetProcAddress (dllhandle_t handle, const char* name)
45 {
46         return (void *)dlsym (handle, name);
47 }
48
49
50 // =======================================================================
51 // General routines
52 // =======================================================================
53
54 void Sys_Quit (void)
55 {
56         Host_Shutdown();
57         fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
58         fflush(stdout);
59         exit(0);
60 }
61
62 void Sys_Error (const char *error, ...)
63 {
64         va_list argptr;
65         char string[1024];
66
67 // change stdin to non blocking
68         fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
69
70         va_start (argptr,error);
71         vsprintf (string,error,argptr);
72         va_end (argptr);
73         fprintf(stderr, "Error: %s\n", string);
74
75         Host_Shutdown ();
76         exit (1);
77
78 }
79
80 void Sys_Warn (const char *warning, ...)
81 {
82         va_list argptr;
83         char string[1024];
84
85         va_start (argptr,warning);
86         vsprintf (string,warning,argptr);
87         va_end (argptr);
88         fprintf(stderr, "Warning: %s", string);
89 }
90
91 double Sys_DoubleTime (void)
92 {
93         static int first = true;
94         static double oldtime = 0.0, curtime = 0.0;
95         double newtime;
96         struct timeval tp;
97
98         gettimeofday(&tp, NULL);
99
100         newtime = (double) tp.tv_sec + tp.tv_usec / 1000000.0;
101
102         if (first)
103         {
104                 first = false;
105                 oldtime = newtime;
106         }
107
108         if (newtime < oldtime)
109         {
110                 // warn if it's significant
111                 if (newtime - oldtime < -0.01)
112                         Con_Printf("Sys_DoubleTime: time stepped backwards (went from %f to %f, difference %f)\n", oldtime, newtime, newtime - oldtime);
113         }
114         else
115                 curtime += newtime - oldtime;
116         oldtime = newtime;
117
118         return curtime;
119 }
120
121 // =======================================================================
122 // Sleeps for microseconds
123 // =======================================================================
124
125 static volatile int oktogo;
126
127 void alarm_handler(int x)
128 {
129         oktogo=1;
130 }
131
132 void floating_point_exception_handler(int whatever)
133 {
134         signal(SIGFPE, floating_point_exception_handler);
135 }
136
137 char *Sys_ConsoleInput(void)
138 {
139         static char text[256];
140         int len;
141         fd_set fdset;
142         struct timeval timeout;
143
144         if (cls.state == ca_dedicated)
145         {
146                 FD_ZERO(&fdset);
147                 FD_SET(0, &fdset); // stdin
148                 timeout.tv_sec = 0;
149                 timeout.tv_usec = 0;
150                 if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
151                         return NULL;
152
153                 len = read (0, text, sizeof(text));
154                 if (len < 1)
155                         return NULL;
156                 text[len-1] = 0;    // rip off the /n and terminate
157
158                 return text;
159         }
160         return NULL;
161 }
162
163 void Sys_Sleep(void)
164 {
165         usleep(1);
166 }
167
168 int main (int argc, const char **argv)
169 {
170         double frameoldtime, framenewtime;
171
172         signal(SIGFPE, SIG_IGN);
173
174         com_argc = argc;
175         com_argv = argv;
176
177         fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
178
179         Sys_Shared_EarlyInit();
180
181         Host_Init();
182
183         Sys_Shared_LateInit();
184
185         frameoldtime = Sys_DoubleTime () - 0.1;
186         while (1)
187         {
188                 // find time spent rendering last frame
189                 framenewtime = Sys_DoubleTime ();
190
191                 Host_Frame (framenewtime - frameoldtime);
192
193                 frameoldtime = framenewtime;
194         }
195         return 0;
196 }