1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 #include <unistd.h>
21 #include <signal.h>
22 #include <stdlib.h>
23 #include <limits.h>
24 #include <sys/time.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <fcntl.h>
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <sys/ipc.h>
31 #include <sys/shm.h>
32 #include <sys/stat.h>
33 #include <string.h>
34 #include <ctype.h>
35 #include <sys/wait.h>
36 #include <sys/mman.h>
37 #include <errno.h>
38
39 #include "quakedef.h"
40
41 int noconinput = 0;
42 int nostdout = 0;
43
44 char *basedir = ".";
45 char *cachedir = "/tmp";
46
47 cvar_t sys_linerefresh = CVAR2("sys_linerefresh","0");// set for entity display
48
49 // =======================================================================
50 // General routines
51 // =======================================================================
52
Sys_DebugNumber(int y,int val)53 void Sys_DebugNumber(int y, int val)
54 {
55 }
56
57 /*
58 void Sys_Printf (char *fmt, ...)
59 {
60 va_list argptr;
61 char text[1024];
62
63 va_start (argptr,fmt);
64 vsprintf (text,fmt,argptr);
65 va_end (argptr);
66 fprintf(stderr, "%s", text);
67
68 Con_Print (text);
69 }
70
71 void Sys_Printf (char *fmt, ...)
72 {
73
74 va_list argptr;
75 char text[1024], *t_p;
76 int l, r;
77
78 if (nostdout)
79 return;
80
81 va_start (argptr,fmt);
82 vsprintf (text,fmt,argptr);
83 va_end (argptr);
84
85 l = strlen(text);
86 t_p = text;
87
88 // make sure everything goes through, even though we are non-blocking
89 while (l)
90 {
91 r = write (1, text, l);
92 if (r != l)
93 sleep (0);
94 if (r > 0)
95 {
96 t_p += r;
97 l -= r;
98 }
99 }
100
101 }
102 */
103
Sys_Printf(char * fmt,...)104 void Sys_Printf (char *fmt, ...)
105 {
106 va_list argptr;
107 char text[2048];
108 unsigned char *p;
109
110 va_start (argptr,fmt);
111 vsprintf (text,fmt,argptr);
112 va_end (argptr);
113
114 if (strlen(text) > sizeof(text))
115 Sys_Error("memory overwrite in Sys_Printf");
116
117 if (nostdout)
118 return;
119
120 for (p = (unsigned char *)text; *p; p++)
121 if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
122 printf("[%02x]", *p);
123 else
124 putc(*p, stdout);
125 }
126
Sys_Quit(void)127 void Sys_Quit (void)
128 {
129 Host_Shutdown();
130 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
131 exit(0);
132 }
133
Sys_Init(void)134 void Sys_Init(void)
135 {
136 #if id386
137 Sys_SetFPCW();
138 #endif
139 }
140
Sys_Error(char * error,...)141 void Sys_Error (char *error, ...)
142 {
143 va_list argptr;
144 char string[1024];
145
146 // change stdin to non blocking
147 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
148
149 va_start (argptr,error);
150 vsprintf (string,error,argptr);
151 va_end (argptr);
152 fprintf(stderr, "Error: %s\n", string);
153
154 Host_Shutdown ();
155 exit (1);
156
157 }
158
Sys_Warn(char * warning,...)159 void Sys_Warn (char *warning, ...)
160 {
161 va_list argptr;
162 char string[1024];
163
164 va_start (argptr,warning);
165 vsprintf (string,warning,argptr);
166 va_end (argptr);
167 fprintf(stderr, "Warning: %s", string);
168 }
169
170 /*
171 ============
172 Sys_FileTime
173
174 returns -1 if not present
175 ============
176 */
Sys_FileTime(char * path)177 int Sys_FileTime (char *path)
178 {
179 struct stat buf;
180
181 if (stat (path,&buf) == -1)
182 return -1;
183
184 return buf.st_mtime;
185 }
186
187
Sys_mkdir(char * path)188 void Sys_mkdir (char *path)
189 {
190 mkdir (path, 0777);
191 }
192
Sys_FileOpenRead(char * path,int * handle)193 int Sys_FileOpenRead (char *path, int *handle)
194 {
195 int h;
196 struct stat fileinfo;
197
198
199 h = open (path, O_RDONLY, 0666);
200 *handle = h;
201 if (h == -1)
202 return -1;
203
204 if (fstat (h,&fileinfo) == -1)
205 Sys_Error ("Error fstating %s", path);
206
207 return fileinfo.st_size;
208 }
209
Sys_FileOpenWrite(char * path)210 int Sys_FileOpenWrite (char *path)
211 {
212 int handle;
213
214 umask (0);
215
216 handle = open(path,O_RDWR | O_CREAT | O_TRUNC
217 , 0666);
218
219 if (handle == -1)
220 Sys_Error ("Error opening %s: %s", path,strerror(errno));
221
222 return handle;
223 }
224
Sys_FileWrite(int handle,void * src,int count)225 int Sys_FileWrite (int handle, void *src, int count)
226 {
227 return write (handle, src, count);
228 }
229
Sys_FileClose(int handle)230 void Sys_FileClose (int handle)
231 {
232 close (handle);
233 }
234
Sys_FileSeek(int handle,int position)235 void Sys_FileSeek (int handle, int position)
236 {
237 lseek (handle, position, SEEK_SET);
238 }
239
Sys_FileRead(int handle,void * dest,int count)240 int Sys_FileRead (int handle, void *dest, int count)
241 {
242 return read (handle, dest, count);
243 }
244
Sys_DebugLog(char * file,char * fmt,...)245 void Sys_DebugLog(char *file, char *fmt, ...)
246 {
247 va_list argptr;
248 static char data[1024];
249 int fd;
250
251 va_start(argptr, fmt);
252 vsprintf(data, fmt, argptr);
253 va_end(argptr);
254 // fd = open(file, O_WRONLY | O_BINARY | O_CREAT | O_APPEND, 0666);
255 fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
256 write(fd, data, strlen(data));
257 close(fd);
258 }
259
Sys_EditFile(char * filename)260 void Sys_EditFile(char *filename)
261 {
262
263 char cmd[256];
264 char *term;
265 char *editor;
266
267 term = getenv("TERM");
268 if (term && !strcmp(term, "xterm"))
269 {
270 editor = getenv("VISUAL");
271 if (!editor)
272 editor = getenv("EDITOR");
273 if (!editor)
274 editor = getenv("EDIT");
275 if (!editor)
276 editor = "vi";
277 sprintf(cmd, "xterm -e %s %s", editor, filename);
278 system(cmd);
279 }
280
281 }
282
Sys_DoubleTime(void)283 double Sys_DoubleTime (void)
284 {
285 struct timeval tp;
286 struct timezone tzp;
287 static int secbase;
288
289 gettimeofday(&tp, &tzp);
290
291 if (!secbase)
292 {
293 secbase = tp.tv_sec;
294 return tp.tv_usec/1000000.0;
295 }
296
297 return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
298 }
299
300 // =======================================================================
301 // Sleeps for microseconds
302 // =======================================================================
303
304 static volatile int oktogo;
305
alarm_handler(int x)306 void alarm_handler(int x)
307 {
308 oktogo=1;
309 }
310
Sys_LineRefresh(void)311 void Sys_LineRefresh(void)
312 {
313 }
314
floating_point_exception_handler(int whatever)315 void floating_point_exception_handler(int whatever)
316 {
317 // Sys_Warn("floating point exception\n");
318 signal(SIGFPE, floating_point_exception_handler);
319 }
320
Sys_ConsoleInput(void)321 char *Sys_ConsoleInput(void)
322 {
323 #if 0
324 static char text[256];
325 int len;
326
327 if (cls.state == ca_dedicated) {
328 len = read (0, text, sizeof(text));
329 if (len < 1)
330 return NULL;
331 text[len-1] = 0; // rip off the /n and terminate
332
333 return text;
334 }
335 #endif
336 return NULL;
337 }
338
339 #if !id386
Sys_HighFPPrecision(void)340 void Sys_HighFPPrecision (void)
341 {
342 }
343
Sys_LowFPPrecision(void)344 void Sys_LowFPPrecision (void)
345 {
346 }
347 #endif
348
349 int skipframes;
350
main(int c,char ** v)351 int main (int c, char **v)
352 {
353
354 double time, oldtime, newtime;
355 quakeparms_t parms;
356 int j;
357
358 // static char cwd[1024];
359
360 // signal(SIGFPE, floating_point_exception_handler);
361 signal(SIGFPE, SIG_IGN);
362
363 memset(&parms, 0, sizeof(parms));
364
365 COM_InitArgv(c, v);
366 parms.argc = com_argc;
367 parms.argv = com_argv;
368
369 parms.memsize = 16*1024*1024;
370
371 j = COM_CheckParm("-mem");
372 if (j)
373 parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024);
374 parms.membase = malloc (parms.memsize);
375
376 parms.basedir = basedir;
377 // caching is disabled by default, use -cachedir to enable
378 // parms.cachedir = cachedir;
379
380 noconinput = COM_CheckParm("-noconinput");
381 if (!noconinput)
382 fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
383
384 if (COM_CheckParm("-nostdout"))
385 nostdout = 1;
386
387 Sys_Init();
388
389 Host_Init(&parms);
390
391 oldtime = Sys_DoubleTime ();
392 while (1)
393 {
394 // find time spent rendering last frame
395 newtime = Sys_DoubleTime ();
396 time = newtime - oldtime;
397
398 Host_Frame(time);
399 oldtime = newtime;
400 }
401
402 }
403
404
405 /*
406 ================
407 Sys_MakeCodeWriteable
408 ================
409 */
Sys_MakeCodeWriteable(unsigned long startaddr,unsigned long length)410 void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
411 {
412
413 int r;
414 unsigned long addr;
415 int psize = getpagesize();
416
417 addr = (startaddr & ~(psize-1)) - psize;
418
419 // fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
420 // addr, startaddr+length, length);
421
422 r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
423
424 if (r < 0)
425 Sys_Error("Protection change failed\n");
426
427 }
428
429