1#include <unistd.h> 2#include <signal.h> 3#include <stdlib.h> 4#include <limits.h> 5#include <sys/time.h> 6#include <sys/types.h> 7#include <unistd.h> 8#include <fcntl.h> 9#include <stdarg.h> 10#include <stdio.h> 11#include <sys/ipc.h> 12#include <sys/shm.h> 13#include <sys/stat.h> 14#include <string.h> 15#include <ctype.h> 16#include <sys/wait.h> 17#include <sys/mman.h> 18#include <errno.h> 19 20#include "quakedef.h" 21 22qboolean isDedicated; 23 24int nostdout = 0; 25 26char *basedir = "."; 27char *cachedir = "/tmp"; 28 29cvar_t sys_linerefresh = {"sys_linerefresh","0"};// set for entity display 30 31// ======================================================================= 32// General routines 33// ======================================================================= 34 35void Sys_DebugNumber(int y, int val) 36{ 37} 38 39/* 40void Sys_Printf (char *fmt, ...) 41{ 42 va_list argptr; 43 char text[1024]; 44 45 va_start (argptr,fmt); 46 vsprintf (text,fmt,argptr); 47 va_end (argptr); 48 fprintf(stderr, "%s", text); 49 50 Con_Print (text); 51} 52 53void Sys_Printf (char *fmt, ...) 54{ 55 56 va_list argptr; 57 char text[1024], *t_p; 58 int l, r; 59 60 if (nostdout) 61 return; 62 63 va_start (argptr,fmt); 64 vsprintf (text,fmt,argptr); 65 va_end (argptr); 66 67 l = strlen(text); 68 t_p = text; 69 70// make sure everything goes through, even though we are non-blocking 71 while (l) 72 { 73 r = write (1, text, l); 74 if (r != l) 75 sleep (0); 76 if (r > 0) 77 { 78 t_p += r; 79 l -= r; 80 } 81 } 82 83} 84*/ 85 86void Sys_Printf (char *fmt, ...) 87{ 88 va_list argptr; 89 char text[1024]; 90 unsigned char *p; 91 92 va_start (argptr,fmt); 93 vsprintf (text,fmt,argptr); 94 va_end (argptr); 95 96 if (strlen(text) > sizeof(text)) 97 Sys_Error("memory overwrite in Sys_Printf"); 98 99 if (nostdout) 100 return; 101 102 for (p = (unsigned char *)text; *p; p++) { 103 *p &= 0x7f; 104 if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9) 105 printf("[%02x]", *p); 106 else 107 putc(*p, stdout); 108 } 109} 110 111#if 0 112static char end1[] = 113"\x1b[?7h\x1b[40m\x1b[2J\x1b[0;1;41m\x1b[1;1H QUAKE: The Doomed Dimension \x1b[33mby \x1b[44mid\x1b[41m Software \x1b[2;1H ---------------------------------------------------------------------------- \x1b[3;1H CALL 1-800-IDGAMES TO ORDER OR FOR TECHNICAL SUPPORT \x1b[4;1H PRICE: $45.00 (PRICES MAY VARY OUTSIDE THE US.) \x1b[5;1H \x1b[6;1H \x1b[37mYes! You only have one fourth of this incredible epic. That is because most \x1b[7;1H of you have paid us nothing or at most, very little. You could steal the \x1b[8;1H game from a friend. But we both know you'll be punished by God if you do. \x1b[9;1H \x1b[33mWHY RISK ETERNAL DAMNATION? CALL 1-800-IDGAMES AND BUY NOW! \x1b[10;1H \x1b[37mRemember, we love you almost as much as He does. \x1b[11;1H \x1b[12;1H \x1b[33mProgramming: \x1b[37mJohn Carmack, Michael Abrash, John Cash \x1b[13;1H \x1b[33mDesign: \x1b[37mJohn Romero, Sandy Petersen, American McGee, Tim Willits \x1b[14;1H \x1b[33mArt: \x1b[37mAdrian Carmack, Kevin Cloud \x1b[15;1H \x1b[33mBiz: \x1b[37mJay Wilbur, Mike Wilson, Donna Jackson \x1b[16;1H \x1b[33mProjects: \x1b[37mShawn Green \x1b[33mSupport: \x1b[37mBarrett Alexander \x1b[17;1H \x1b[33mSound Effects: \x1b[37mTrent Reznor and Nine Inch Nails \x1b[18;1H For other information or details on ordering outside the US, check out the \x1b[19;1H files accompanying QUAKE or our website at http://www.idsoftware.com. \x1b[20;1H \x1b[0;41mQuake is a trademark of Id Software, inc., (c)1996 Id Software, inc. \x1b[21;1H All rights reserved. NIN logo is a registered trademark licensed to \x1b[22;1H Nothing Interactive, Inc. All rights reserved. \x1b[40m\x1b[23;1H\x1b[0m"; 114static char end2[] = 115"\x1b[?7h\x1b[40m\x1b[2J\x1b[0;1;41m\x1b[1;1H QUAKE \x1b[33mby \x1b[44mid\x1b[41m Software \x1b[2;1H ----------------------------------------------------------------------------- \x1b[3;1H \x1b[37mWhy did you quit from the registered version of QUAKE? Did the \x1b[4;1H scary monsters frighten you? Or did Mr. Sandman tug at your \x1b[5;1H little lids? No matter! What is important is you love our \x1b[6;1H game, and gave us your money. Congratulations, you are probably \x1b[7;1H not a thief. \x1b[8;1H Thank You. \x1b[9;1H \x1b[33;44mid\x1b[41m Software is: \x1b[10;1H PROGRAMMING: \x1b[37mJohn Carmack, Michael Abrash, John Cash \x1b[11;1H \x1b[33mDESIGN: \x1b[37mJohn Romero, Sandy Petersen, American McGee, Tim Willits \x1b[12;1H \x1b[33mART: \x1b[37mAdrian Carmack, Kevin Cloud \x1b[13;1H \x1b[33mBIZ: \x1b[37mJay Wilbur, Mike Wilson \x1b[33mPROJECTS MAN: \x1b[37mShawn Green \x1b[14;1H \x1b[33mBIZ ASSIST: \x1b[37mDonna Jackson \x1b[33mSUPPORT: \x1b[37mBarrett Alexander \x1b[15;1H \x1b[33mSOUND EFFECTS AND MUSIC: \x1b[37mTrent Reznor and Nine Inch Nails \x1b[16;1H \x1b[17;1H If you need help running QUAKE refer to the text files in the \x1b[18;1H QUAKE directory, or our website at http://www.idsoftware.com. \x1b[19;1H If all else fails, call our technical support at 1-800-IDGAMES. \x1b[20;1H \x1b[0;41mQuake is a trademark of Id Software, inc., (c)1996 Id Software, inc. \x1b[21;1H All rights reserved. NIN logo is a registered trademark licensed \x1b[22;1H to Nothing Interactive, Inc. All rights reserved. \x1b[23;1H\x1b[40m\x1b[0m"; 116 117#endif 118void Sys_Quit (void) 119{ 120 Host_Shutdown(); 121 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); 122#if 0 123 if (registered.value) 124 printf("%s", end2); 125 else 126 printf("%s", end1); 127#endif 128 fflush(stdout); 129 exit(0); 130} 131 132void Sys_Init(void) 133{ 134#if id386 135 Sys_SetFPCW(); 136#endif 137} 138 139void Sys_Error (char *error, ...) 140{ 141 va_list argptr; 142 char string[1024]; 143 144// change stdin to non blocking 145 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); 146 147 va_start (argptr,error); 148 vsprintf (string,error,argptr); 149 va_end (argptr); 150 fprintf(stderr, "Error: %s\n", string); 151 152 Host_Shutdown (); 153 exit (1); 154 155} 156 157void Sys_Warn (char *warning, ...) 158{ 159 va_list argptr; 160 char string[1024]; 161 162 va_start (argptr,warning); 163 vsprintf (string,warning,argptr); 164 va_end (argptr); 165 fprintf(stderr, "Warning: %s", string); 166} 167 168/* 169============ 170Sys_FileTime 171 172returns -1 if not present 173============ 174*/ 175int Sys_FileTime (char *path) 176{ 177 struct stat buf; 178 179 if (stat (path,&buf) == -1) 180 return -1; 181 182 return buf.st_mtime; 183} 184 185 186void Sys_mkdir (char *path) 187{ 188 mkdir (path, 0777); 189} 190 191int Sys_FileOpenRead (char *path, int *handle) 192{ 193 int h; 194 struct stat fileinfo; 195 196 197 h = open (path, O_RDONLY, 0666); 198 *handle = h; 199 if (h == -1) 200 return -1; 201 202 if (fstat (h,&fileinfo) == -1) 203 Sys_Error ("Error fstating %s", path); 204 205 return fileinfo.st_size; 206} 207 208int Sys_FileOpenWrite (char *path) 209{ 210 int handle; 211 212 umask (0); 213 214 handle = open(path,O_RDWR | O_CREAT | O_TRUNC 215 , 0666); 216 217 if (handle == -1) 218 Sys_Error ("Error opening %s: %s", path,strerror(errno)); 219 220 return handle; 221} 222 223int Sys_FileWrite (int handle, void *src, int count) 224{ 225 return write (handle, src, count); 226} 227 228void Sys_FileClose (int handle) 229{ 230 close (handle); 231} 232 233void Sys_FileSeek (int handle, int position) 234{ 235 lseek (handle, position, SEEK_SET); 236} 237 238int Sys_FileRead (int handle, void *dest, int count) 239{ 240 return read (handle, dest, count); 241} 242 243void Sys_DebugLog(char *file, char *fmt, ...) 244{ 245 va_list argptr; 246 static char data[1024]; 247 int fd; 248 249 va_start(argptr, fmt); 250 vsprintf(data, fmt, argptr); 251 va_end(argptr); 252// fd = open(file, O_WRONLY | O_BINARY | O_CREAT | O_APPEND, 0666); 253 fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666); 254 write(fd, data, strlen(data)); 255 close(fd); 256} 257 258void Sys_EditFile(char *filename) 259{ 260 261 char cmd[256]; 262 char *term; 263 char *editor; 264 265 term = getenv("TERM"); 266 if (term && !strcmp(term, "xterm")) 267 { 268 editor = getenv("VISUAL"); 269 if (!editor) 270 editor = getenv("EDITOR"); 271 if (!editor) 272 editor = getenv("EDIT"); 273 if (!editor) 274 editor = "vi"; 275 sprintf(cmd, "xterm -e %s %s", editor, filename); 276 system(cmd); 277 } 278 279} 280 281double Sys_FloatTime (void) 282{ 283 struct timeval tp; 284 struct timezone tzp; 285 static int secbase; 286 287 gettimeofday(&tp, &tzp); 288 289 if (!secbase) 290 { 291 secbase = tp.tv_sec; 292 return tp.tv_usec/1000000.0; 293 } 294 295 return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0; 296} 297 298// ======================================================================= 299// Sleeps for microseconds 300// ======================================================================= 301 302static volatile int oktogo; 303 304void alarm_handler(int x) 305{ 306 oktogo=1; 307} 308 309void Sys_LineRefresh(void) 310{ 311} 312 313void floating_point_exception_handler(int whatever) 314{ 315// Sys_Warn("floating point exception\n"); 316 signal(SIGFPE, floating_point_exception_handler); 317} 318 319char *Sys_ConsoleInput(void) 320{ 321 static char text[256]; 322 int len; 323 fd_set fdset; 324 struct timeval timeout; 325 326 if (cls.state == ca_dedicated) { 327 FD_ZERO(&fdset); 328 FD_SET(0, &fdset); // stdin 329 timeout.tv_sec = 0; 330 timeout.tv_usec = 0; 331 if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset)) 332 return NULL; 333 334 len = read (0, text, sizeof(text)); 335 if (len < 1) 336 return NULL; 337 text[len-1] = 0; // rip off the /n and terminate 338 339 return text; 340 } 341 return NULL; 342} 343 344#if !id386 345void Sys_HighFPPrecision (void) 346{ 347} 348 349void Sys_LowFPPrecision (void) 350{ 351} 352#endif 353 354int main (int c, char **v) 355{ 356 357 double time, oldtime, newtime; 358 quakeparms_t parms; 359 extern int vcrFile; 360 extern int recording; 361 int j; 362 363// static char cwd[1024]; 364 365// signal(SIGFPE, floating_point_exception_handler); 366 signal(SIGFPE, SIG_IGN); 367 368 memset(&parms, 0, sizeof(parms)); 369 370 COM_InitArgv(c, v); 371 parms.argc = com_argc; 372 parms.argv = com_argv; 373 374#ifdef GLQUAKE 375 parms.memsize = 16*1024*1024; 376#else 377 parms.memsize = 8*1024*1024; 378#endif 379 380 j = COM_CheckParm("-mem"); 381 if (j) 382 parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024); 383 parms.membase = malloc (parms.memsize); 384 385 parms.basedir = basedir; 386// caching is disabled by default, use -cachedir to enable 387// parms.cachedir = cachedir; 388 389 fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); 390 391 Host_Init(&parms); 392 393 Sys_Init(); 394 395 if (COM_CheckParm("-nostdout")) 396 nostdout = 1; 397 else { 398 fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); 399 printf ("Linux Quake -- Version %0.3f\n", LINUX_VERSION); 400 } 401 402 oldtime = Sys_FloatTime () - 0.1; 403 while (1) 404 { 405// find time spent rendering last frame 406 newtime = Sys_FloatTime (); 407 time = newtime - oldtime; 408 409 if (cls.state == ca_dedicated) 410 { // play vcrfiles at max speed 411 if (time < sys_ticrate.value && (vcrFile == -1 || recording) ) 412 { 413 usleep(1); 414 continue; // not time to run a server only tic yet 415 } 416 time = sys_ticrate.value; 417 } 418 419 if (time > sys_ticrate.value*2) 420 oldtime = newtime; 421 else 422 oldtime += time; 423 424 Host_Frame (time); 425 426// graphic debugging aids 427 if (sys_linerefresh.value) 428 Sys_LineRefresh (); 429 } 430 431} 432 433 434/* 435================ 436Sys_MakeCodeWriteable 437================ 438*/ 439void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length) 440{ 441 442 int r; 443 unsigned long addr; 444 int psize = getpagesize(); 445 446 addr = (startaddr & ~(psize-1)) - psize; 447 448// fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr, 449// addr, startaddr+length, length); 450 451 r = mprotect((char*)addr, length + startaddr - addr + psize, 7); 452 453 if (r < 0) 454 Sys_Error("Protection change failed\n"); 455 456} 457 458