|
|
1.1 root 1: #include <libc.h>
2: #include <mach/mach.h>
3: #include <appkit/appkit.h>
4: #include <sys/types.h>
5: #include <sys/dir.h>
6: #include "quakedef.h"
7:
8: cvar_t sys_linerefresh = {"sys_linerefresh","0"};// set for entity display
9: cvar_t sys_nostdout = {"sys_nostdout","0"};
10: cvar_t sys_nosleep = {"sys_nosleep","0"};
11:
12: static char *basedir = "/raid/quake";
13: static char *cachedir = "/qcache";
14:
15: void Sys_SetLowFPPrecision (void);
16: void Sys_SetHighFPPrecision (void);
17: void Sys_DoSetFPCW (void);
18:
19:
20: /*
21: ===============================================================================
22:
23: REQUIRED SYS FUNCTIONS
24:
25: ===============================================================================
26: */
27:
28: /*
29: ============
30: Sys_FileTime
31:
32: returns -1 if not present
33: ============
34: */
35: int Sys_FileTime (char *path)
36: {
37: struct stat buf;
38:
39: if (stat (path,&buf) == -1)
40: return -1;
41:
42: return buf.st_mtime;
43: }
44:
45:
46: void Sys_mkdir (char *path)
47: {
48: if (mkdir (path, 0777) != -1)
49: return;
50: if (errno != EEXIST)
51: Sys_Error ("mkdir %s: %s",path, strerror(errno));
52: }
53:
54: int Sys_FileOpenRead (char *path, int *handle)
55: {
56: int h;
57: struct stat fileinfo;
58:
59: h = open (path, O_RDONLY, 0666);
60: *handle = h;
61: if (h == -1)
62: return -1;
63:
64: if (fstat (h,&fileinfo) == -1)
65: Sys_Error ("Error fstating %s", path);
66:
67: return fileinfo.st_size;
68: }
69:
70: int Sys_FileOpenWrite (char *path)
71: {
72: int handle;
73:
74: umask (0);
75:
76: handle = open(path,O_RDWR | O_CREAT | O_TRUNC
77: , 0666);
78:
79: if (handle == -1)
80: Sys_Error ("Error opening %s: %s", path,strerror(errno));
81:
82: return handle;
83: }
84:
85: void Sys_FileClose (int handle)
86: {
87: close (handle);
88: }
89:
90: void Sys_FileSeek (int handle, int position)
91: {
92: lseek (handle, position, SEEK_SET);
93: }
94:
95: int Sys_FileRead (int handle, void *dest, int count)
96: {
97: return read (handle, dest, count);
98: }
99:
100: int Sys_FileWrite (int handle, void *data, int count)
101: {
102: return write (handle, data, count);
103: }
104:
105:
106: /*
107: ============
108: Sys_SetFPCW
109: ============
110: */
111: void Sys_SetFPCW (void)
112: {
113: #if id386
114: Sys_DoSetFPCW ();
115: #endif
116: }
117:
118:
119: #if !id386
120:
121: /*
122: ================
123: Sys_LowFPPrecision
124: ================
125: */
126: void Sys_LowFPPrecision (void)
127: {
128: // causes weird problems on Nextstep
129: }
130:
131:
132: /*
133: ================
134: Sys_HighFPPrecision
135: ================
136: */
137: void Sys_HighFPPrecision (void)
138: {
139: // causes weird problems on Nextstep
140: }
141:
142: #endif // !id386
143:
144:
145: void Sys_DebugLog(char *file, char *fmt, ...)
146: {
147: va_list argptr;
148: static char data[1024];
149: int fd;
150:
151: va_start(argptr, fmt);
152: vsprintf(data, fmt, argptr);
153: va_end(argptr);
154: fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);
155: write(fd, data, strlen(data));
156: close(fd);
157: }
158:
159:
160: /*
161: ================
162: Sys_MakeCodeWriteable
163: ================
164: */
165: void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
166: {
167: kern_return_t r;
168:
169: r = vm_protect(task_self(),
170: (vm_address_t)startaddr,
171: length,
172: FALSE,
173: VM_PROT_WRITE | VM_PROT_READ | VM_PROT_EXECUTE);
174:
175: if (r != KERN_SUCCESS)
176: Sys_Error("Protection change failed\n");
177: }
178:
179:
180: /*
181: ================
182: Sys_FloatTime
183: ================
184: */
185: double Sys_FloatTime (void)
186: {
187: struct timeval tp;
188: struct timezone tzp;
189: static int secbase;
190:
191: gettimeofday(&tp, &tzp);
192:
193: if (!secbase)
194: {
195: secbase = tp.tv_sec;
196: return tp.tv_usec/1000000.0;
197: }
198:
199: return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
200: }
201:
202: /*
203: ================
204: Sys_Error
205: ================
206: */
207: void Sys_Error (char *error, ...)
208: {
209: va_list argptr;
210: char string[1024];
211:
212: // change stdin to non blocking
213: fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
214:
215: va_start (argptr,error);
216: vsprintf (string,error,argptr);
217: va_end (argptr);
218: printf ("Fatal error: %s\n",string);
219:
220: if (!NXApp)
221: { // appkit isn't running, so don't try to pop up a panel
222: Host_Shutdown ();
223: exit (1);
224: }
225: NXRunAlertPanel ("Error",string,NULL,NULL,NULL);
226: [NXApp terminate: NULL];
227: }
228:
229: /*
230: ================
231: Sys_Printf
232: ================
233: */
234: void Sys_Printf (char *fmt, ...)
235: {
236: va_list argptr;
237: char text[1024], *t_p;
238: int l, r;
239:
240: if (sys_nostdout.value)
241: return;
242:
243: va_start (argptr,fmt);
244: vsprintf (text,fmt,argptr);
245: va_end (argptr);
246:
247: l = strlen(text);
248: t_p = text;
249:
250: // make sure everything goes through, even though we are non-blocking
251: while (l)
252: {
253: r = write (1, text, l);
254: if (r != l)
255: sleep (0);
256: if (r > 0)
257: {
258: t_p += r;
259: l -= r;
260: }
261: }
262: }
263:
264: /*
265: ================
266: Sys_Quit
267: ================
268: */
269: void Sys_Quit (void)
270: {
271: Host_Shutdown();
272:
273: // change stdin to blocking
274: fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
275:
276: if (!NXApp)
277: exit (0); // appkit isn't running
278:
279: [NXApp terminate:nil];
280: }
281:
282:
283: /*
284: ================
285: Sys_Init
286: ================
287: */
288: void Sys_Init(void)
289: {
290:
291: Sys_SetFPCW ();
292: }
293:
294:
295: /*
296: ================
297: Sys_Sleep
298: ================
299: */
300: void Sys_Sleep (void)
301: {
302: usleep (10);
303: }
304:
305:
306: /*
307: ================
308: Sys_SendKeyEvents
309:
310: service any pending appkit events
311: ================
312: */
313: void Sys_SendKeyEvents (void)
314: {
315: NXEvent *event;
316:
317: while ( (event = [NXApp
318: getNextEvent: 0xffffffff
319: waitFor: 0
320: threshold: NX_BASETHRESHOLD] ) )
321: {
322: [NXApp sendEvent: event];
323: }
324: }
325:
326:
327: /*
328: ================
329: Sys_ConsoleInput
330:
331: Checks for a complete line of text typed in at the console, then forwards
332: it to the host command processor
333: ================
334: */
335: char *Sys_ConsoleInput (void)
336: {
337: static char text[256];
338: int len;
339:
340: len = read (0, text, sizeof(text));
341: if (len < 1)
342: return NULL;
343: text[len-1] = 0; // rip off the /n and terminate
344:
345: return text;
346: }
347:
348: /*
349: ==============================================================================
350:
351: graphic debugging tools
352:
353: ==============================================================================
354: */
355:
356: id lineview_i, linewindow_i;
357: NXRect linebounds;
358:
359: int window=-1;
360:
361: void SV_OpenLineWindow (void)
362: {
363: float w, h, max;
364: float scale;
365:
366: if (!NXApp)
367: [Application new];
368:
369:
370: w = sv.worldmodel->maxs[0] - sv.worldmodel->mins[0] + 32;
371: h = sv.worldmodel->maxs[1] - sv.worldmodel->mins[1] + 32;
372: max = w>h ? w : h;
373: scale = 512/max;
374: #if 0
375: scale = 1.0;
376: while (max > 512)
377: {
378: max /= 2;
379: scale /= 2;
380: }
381: #endif
382: NXSetRect (&linebounds, 0,0, w*scale, h*scale);
383:
384: linewindow_i =
385: [[Window alloc]
386: initContent: &linebounds
387: style: NX_TITLEDSTYLE
388: backing: NX_BUFFERED
389: buttonMask: 0
390: defer: NO
391: ];
392:
393: [linewindow_i display];
394: [linewindow_i orderFront: nil];
395: lineview_i = [linewindow_i contentView];
396:
397: [lineview_i setDrawSize: w : h];
398:
399: [lineview_i setDrawOrigin: sv.worldmodel->mins[0] - 16 : sv.worldmodel->mins[1] - 16];
400:
401: [lineview_i getBounds: &linebounds];
402:
403: }
404:
405: void Sys_Clear (void)
406: {
407: if (!lineview_i)
408: return;
409:
410: [lineview_i lockFocus];
411: NXEraseRect (&linebounds);
412: [lineview_i unlockFocus];
413: }
414:
415: void Sys_LineRefresh (void)
416: {
417: int i;
418: edict_t *ent;
419: float *org, *mins, *maxs;
420: model_t *mod;
421:
422: if (!sv.active)
423: return;
424:
425: if (!lineview_i)
426: SV_OpenLineWindow ();
427:
428: [lineview_i lockFocus];
429: NXEraseRect (&linebounds);
430:
431: mod = sv.worldmodel;
432:
433: PSsetgray (0);
434: PSmoveto (mod->mins[0], mod->mins[1]);
435: PSlineto (mod->mins[0], mod->maxs[1]);
436: PSlineto (mod->maxs[0], mod->maxs[1]);
437: PSlineto (mod->maxs[0], mod->mins[1]);
438: PSlineto (mod->mins[0], mod->mins[1]);
439:
440:
441: for (i=1 ; i<sv.num_edicts ; i++)
442: {
443: ent = EDICT_NUM(i);
444: if (ent->free)
445: continue;
446:
447: switch ((int)ent->v.solid)
448: {
449: case SOLID_NOT:
450: PSsetrgbcolor (0, 0, 1);
451: break;
452:
453: case SOLID_TRIGGER:
454: PSsetrgbcolor (0, 1, 0);
455: break;
456:
457: default:
458: PSsetgray (0);
459: break;
460: }
461:
462: org = ent->v.origin;
463: mins = ent->v.mins;
464: maxs = ent->v.maxs;
465:
466: if (maxs[0] - mins[0] == 0)
467: {
468: PSarc (org[0], org[1], 8, 0, 360);
469: }
470: else
471: {
472: PSmoveto (org[0] + mins[0], org[1] + mins[1]);
473: PSlineto (org[0] + mins[0], org[1] + maxs[1]);
474: PSlineto (org[0] + maxs[0], org[1] + maxs[1]);
475: PSlineto (org[0] + maxs[0], org[1] + mins[1]);
476: PSlineto (org[0] + mins[0], org[1] + mins[1]);
477: }
478: PSstroke ();
479: }
480:
481: PSstroke ();
482:
483: [lineview_i unlockFocus];
484: [linewindow_i flushWindow];
485: NXPing ();
486: }
487:
488:
489: void SV_DrawLine (vec3_t v1, vec3_t v2)
490: {
491: if (!lineview_i)
492: return;
493: [lineview_i lockFocus];
494: PSmoveto (v1[0],v1[1]);
495: PSlineto (v2[0],v2[1]);
496: PSstroke ();
497: [lineview_i unlockFocus];
498: [linewindow_i flushWindow];
499: NXPing ();
500: }
501:
502: //============================================================================
503:
504:
505: /*
506: =============
507: main
508: =============
509: */
510: void main(int argc, char *argv[])
511: {
512: double time, oldtime, newtime;
513: quakeparms_t parms;
514: extern int vcrFile;
515: extern int recording;
516: static int frame;
517:
518: moncontrol(0); // turn off profiling except during real Quake work
519:
520: // change stdin to non blocking
521: fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
522:
523: parms.memsize = 5861376;
524: // parms.memsize = 12*1024*1024;
525: parms.membase = malloc (parms.memsize);
526: parms.basedir = basedir;
527: parms.cachedir = cachedir;
528:
529: COM_InitArgv (NXArgc, NXArgv);
530:
531: parms.argc = com_argc;
532: parms.argv = com_argv;
533:
534: Sys_Init ();
535:
536: Host_Init (&parms);
537:
538: Cvar_RegisterVariable (&sys_nostdout);
539: Cvar_RegisterVariable (&sys_linerefresh);
540: Cvar_RegisterVariable (&sys_nosleep);
541:
542: //
543: // main loop
544: //
545: oldtime = Sys_FloatTime () - 0.1;
546: while (1)
547: {
548: // find time spent rendering last frame
549: newtime = Sys_FloatTime ();
550: time = newtime - oldtime;
551:
552: if (cls.state == ca_dedicated)
553: { // play vcrfiles at max speed
554: if (time < sys_ticrate.value && (vcrFile == -1 || recording) )
555: {
556: if (!sys_nosleep.value)
557: usleep (1);
558: continue; // not time to run a server only tic yet
559: }
560: time = sys_ticrate.value;
561: }
562:
563: if (time > sys_ticrate.value*2)
564: oldtime = newtime;
565: else
566: oldtime += time;
567:
568: if (++frame > 10)
569: moncontrol(1); // profile only while we do each Quake frame
570: Host_Frame (time);
571: moncontrol(0);
572:
573: // graphic debugging aids
574: if (sys_linerefresh.value)
575: Sys_LineRefresh ();
576: }
577: }
578:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.