#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "quakedef.h" int noconinput = 0; char *basedir = "."; char *cachedir = "/tmp"; cvar_t sys_linerefresh = { "sys_linerefresh", "0" }; // set for entity display cvar_t sys_nostdout = { "sys_nostdout", "0" }; // ======================================================================= // General routines // ======================================================================= void Sys_DebugNumber(int y, int val) { } /* void Sys_Printf (char *fmt, ...) { va_list argptr; char text[1024]; va_start (argptr,fmt); vsprintf (text,fmt,argptr); va_end (argptr); fprintf(stderr, "%s", text); Con_Print (text); } */ void Sys_Printf(char *fmt, ...) { va_list argptr; char text[1024], *t_p; int l, r; if (sys_nostdout.value) return; va_start(argptr, fmt); vsprintf(text, fmt, argptr); va_end(argptr); l = strlen(text); t_p = text; // make sure everything goes through, even though we are non-blocking while (l) { r = write(1, text, l); if (r != l) sleep(0); if (r > 0) { t_p += r; l -= r; } } } void Sys_Quit(void) { Host_Shutdown(); fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~FNDELAY); exit(0); } void Sys_Init(void) { } void Sys_Error(char *error, ...) { va_list argptr; char string[1024]; // change stdin to non blocking fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) & ~FNDELAY); va_start(argptr, error); vsprintf(string, error, argptr); va_end(argptr); fprintf(stderr, "Error: %s\n", string); Host_Shutdown(); exit(1); } void Sys_Warn(char *warning, ...) { va_list argptr; char string[1024]; va_start(argptr, warning); vsprintf(string, warning, argptr); va_end(argptr); fprintf(stderr, "Warning: %s", string); } /* ============ Sys_FileTime returns -1 if not present ============ */ int Sys_FileTime(char *path) { struct stat buf; if (stat(path, &buf) == -1) return -1; return buf.st_mtime; } void Sys_mkdir(char *path) { mkdir(path, 0777); } int Sys_FileOpenRead(char *path, int *handle) { int h; struct stat fileinfo; h = open(path, O_RDONLY, 0666); *handle = h; if (h == -1) return -1; if (fstat(h, &fileinfo) == -1) Sys_Error("Error fstating %s", path); return fileinfo.st_size; } int Sys_FileOpenWrite(char *path) { int handle; umask(0); handle = open(path, O_RDWR | O_CREAT | O_TRUNC, 0666); if (handle == -1) Sys_Error("Error opening %s: %s", path, strerror(errno)); return handle; } int Sys_FileWrite(int handle, void *src, int count) { return write(handle, src, count); } void Sys_FileClose(int handle) { close(handle); } void Sys_FileSeek(int handle, int position) { lseek(handle, position, SEEK_SET); } int Sys_FileRead(int handle, void *dest, int count) { return read(handle, dest, count); } void Sys_DebugLog(char *file, char *fmt, ...) { va_list argptr; static char data[1024]; int fd; va_start(argptr, fmt); vsprintf(data, fmt, argptr); va_end(argptr); // fd = open(file, O_WRONLY | O_BINARY | O_CREAT | O_APPEND, 0666); fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666); write(fd, data, strlen(data)); close(fd); } void Sys_EditFile(char *filename) { char cmd[256]; char *term; char *editor; term = getenv("TERM"); if (term && !strcmp(term, "xterm")) { editor = getenv("VISUAL"); if (!editor) editor = getenv("EDITOR"); if (!editor) editor = getenv("EDIT"); if (!editor) editor = "vi"; sprintf(cmd, "xterm -e %s %s", editor, filename); system(cmd); } } double Sys_FloatTime(void) { struct timeval tp; struct timezone tzp; static int secbase; gettimeofday(&tp, &tzp); if (!secbase) { secbase = tp.tv_sec; return tp.tv_usec / 1000000.0; } return (tp.tv_sec - secbase) + tp.tv_usec / 1000000.0; } // ======================================================================= // Sleeps for microseconds // ======================================================================= static volatile int oktogo; void alarm_handler(int x) { oktogo = 1; } byte *Sys_ZoneBase(int *size) { char *QUAKEOPT = getenv("QUAKEOPT"); *size = 0xc00000; if (QUAKEOPT) { while (*QUAKEOPT) if (tolower(*QUAKEOPT++) == 'm') { *size = atof(QUAKEOPT) * 1024 * 1024; break; } } return malloc(*size); } void Sys_LineRefresh(void) { } void Sys_Sleep(void) { usleep(10); } void floating_point_exception_handler(int whatever) { // Sys_Warn("floating point exception\n"); signal(SIGFPE, floating_point_exception_handler); } /* char *Sys_ConsoleInput(void) { static char text[256]; int len; len = read (0, text, sizeof(text)); if (len < 1) return NULL; text[len-1] = 0; // rip off the /n and terminate return text; } */ void moncontrol(int x) { } int main(int c, char **v) { double time, oldtime, newtime; quakeparms_t parms; extern int vcrFile; extern int recording; static int frame; // static char cwd[1024]; moncontrol(0); /* signal(SIGFPE, floating_point_exception_handler); */ signal(SIGFPE, SIG_IGN); noconinput = COM_CheckParm("-noconinput"); if (!noconinput) fcntl(0, F_SETFL, fcntl(0, F_GETFL, 0) | FNDELAY); // getcwd(cwd); // if (cwd[Q_strlen(cwd)-1] == '/') cwd[Q_strlen(cwd)-1] = 0; // parms.basedir = cwd; parms.memsize = 8 * 1024 * 1024; parms.membase = malloc(parms.memsize); parms.basedir = basedir; parms.cachedir = cachedir; COM_InitArgv(c, v); parms.argc = com_argc; parms.argv = com_argv; Sys_Init(); Host_Init(&parms); Cvar_RegisterVariable(&sys_nostdout); oldtime = Sys_FloatTime() - 0.1; while (1) { usleep(1000); // find time spent rendering last frame newtime = Sys_FloatTime(); time = newtime - oldtime; if (cls.state == ca_dedicated) { // play vcrfiles at max speed if (time < sys_ticrate.value && (vcrFile == -1 || recording)) { usleep(1); continue; // not time to run a server only tic yet } time = sys_ticrate.value; } if (time > sys_ticrate.value * 2) oldtime = newtime; else oldtime += time; if (++frame > 10) moncontrol(1); // profile only while we do each Quake frame Host_Frame(time); moncontrol(0); // graphic debugging aids if (sys_linerefresh.value) Sys_LineRefresh(); } } /* ================ Sys_MakeCodeWriteable ================ */ void Sys_MakeCodeWriteable(unsigned long startaddr, unsigned long length) { int r; unsigned long addr; int psize = getpagesize(); fprintf(stderr, "writable code %lx-%lx\n", startaddr, startaddr + length); addr = startaddr & ~(psize - 1); r = mprotect((char *) addr, length + startaddr - addr, 7); if (r < 0) Sys_Error("Protection change failed\n"); }