1/* 2Copyright (C) 1996-1997 Id Software, Inc. 3 4This program is free software; you can redistribute it and/or 5modify it under the terms of the GNU General Public License 6as published by the Free Software Foundation; either version 2 7of the License, or (at your option) any later version. 8 9This program is distributed in the hope that it will be useful, 10but WITHOUT ANY WARRANTY; without even the implied warranty of 11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 13See the GNU General Public License for more details. 14 15You should have received a copy of the GNU General Public License 16along with this program; if not, write to the Free Software 17Foundation, 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 41int noconinput = 0; 42int nostdout = 0; 43 44char *basedir = "."; 45char *cachedir = "/tmp"; 46 47cvar_t sys_linerefresh = CVAR2("sys_linerefresh","0");// set for entity display 48 49// ======================================================================= 50// General routines 51// ======================================================================= 52 53void Sys_DebugNumber(int y, int val) 54{ 55} 56 57/* 58void 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 71void 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 104void 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 127void Sys_Quit (void) 128{ 129 Host_Shutdown(); 130 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); 131 exit(0); 132} 133 134void Sys_Init(void) 135{ 136#if id386 137 Sys_SetFPCW(); 138#endif 139} 140 141void 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 159void 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============ 172Sys_FileTime 173 174returns -1 if not present 175============ 176*/ 177int 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 188void Sys_mkdir (char *path) 189{ 190 mkdir (path, 0777); 191} 192 193int 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 210int 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 225int Sys_FileWrite (int handle, void *src, int count) 226{ 227 return write (handle, src, count); 228} 229 230void Sys_FileClose (int handle) 231{ 232 close (handle); 233} 234 235void Sys_FileSeek (int handle, int position) 236{ 237 lseek (handle, position, SEEK_SET); 238} 239 240int Sys_FileRead (int handle, void *dest, int count) 241{ 242 return read (handle, dest, count); 243} 244 245void 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 260void 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 283double 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 304static volatile int oktogo; 305 306void alarm_handler(int x) 307{ 308 oktogo=1; 309} 310 311void Sys_LineRefresh(void) 312{ 313} 314 315void floating_point_exception_handler(int whatever) 316{ 317// Sys_Warn("floating point exception\n"); 318 signal(SIGFPE, floating_point_exception_handler); 319} 320 321char *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 340void Sys_HighFPPrecision (void) 341{ 342} 343 344void Sys_LowFPPrecision (void) 345{ 346} 347#endif 348 349int skipframes; 350 351int 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================ 407Sys_MakeCodeWriteable 408================ 409*/ 410void 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