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 22 qboolean isDedicated; 23 24 int nostdout = 0; 25 26 char *basedir = "."; 27 char *cachedir = "/tmp"; 28 29 cvar_t sys_linerefresh = {"sys_linerefresh","0"};// set for entity display 30 31 // ======================================================================= 32 // General routines 33 // ======================================================================= 34 35 void Sys_DebugNumber(int y, int val) 36 { 37 } 38 39 /* 40 void 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 53 void 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 86 void 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 112 static 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"; 114 static 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 118 void 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 132 void Sys_Init(void) 133 { 134 #if id386 135 Sys_SetFPCW(); 136 #endif 137 } 138 139 void 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 157 void 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 ============ 170 Sys_FileTime 171 172 returns -1 if not present 173 ============ 174 */ 175 int 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 186 void Sys_mkdir (char *path) 187 { 188 mkdir (path, 0777); 189 } 190 191 int 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 208 int 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 223 int Sys_FileWrite (int handle, void *src, int count) 224 { 225 return write (handle, src, count); 226 } 227 228 void Sys_FileClose (int handle) 229 { 230 close (handle); 231 } 232 233 void Sys_FileSeek (int handle, int position) 234 { 235 lseek (handle, position, SEEK_SET); 236 } 237 238 int Sys_FileRead (int handle, void *dest, int count) 239 { 240 return read (handle, dest, count); 241 } 242 243 void 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 258 void 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 281 double 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 302 static volatile int oktogo; 303 304 void alarm_handler(int x) 305 { 306 oktogo=1; 307 } 308 309 void Sys_LineRefresh(void) 310 { 311 } 312 313 void floating_point_exception_handler(int whatever) 314 { 315 // Sys_Warn("floating point exception\n"); 316 signal(SIGFPE, floating_point_exception_handler); 317 } 318 319 char *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 345 void Sys_HighFPPrecision (void) 346 { 347 } 348 349 void Sys_LowFPPrecision (void) 350 { 351 } 352 #endif 353 354 int 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 ================ 436 Sys_MakeCodeWriteable 437 ================ 438 */ 439 void 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