ref: 4a40fbd789b5308e3904cb73b164f3f8f270c4d0
dir: /sys_unix.c/
#include "quakedef.h"
#include "parg.h"
#include <time.h>
#include <errno.h>
#include <fenv.h>
char *game;
int debug;
char lasterr[256] = {0};
static const char *disabled[32];
static int ndisabled;
bool
isdisabled(char *s)
{
int i;
for(i = 0; i < ndisabled; i++){
if(strcmp(disabled[i], s) == 0)
return true;
}
return false;
}
char *
lerr(void)
{
static char lasterrcopy[256];
if(*lasterr == 0 && errno != 0)
return strerror(errno);
strcpy(lasterrcopy, lasterr);
return lasterrcopy;
}
int
sys_mkdir(char *path)
{
return (mkdir(path, 0770) == 0 || errno == EEXIST) ? 0 : -1;
}
char *
sys_timestamp(void)
{
static char ts[32];
struct tm *tm;
time_t t;
if((t = time(nil)) == (time_t)-1 || (tm = localtime(&t)) == nil)
return nil;
snprint(ts, sizeof(ts),
"%04d%02d%02d-%02d%02d%02d",
tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec
);
return ts;
}
void
fatal(char *fmt, ...)
{
va_list arg;
va_start(arg, fmt);
vfprintf(stderr, fmt, arg);
va_end(arg);
Host_Shutdown();
exit(1);
}
void *
emalloc(long n)
{
void *p;
if(p = calloc(1, n), p == nil)
fatal("emalloc");
setmalloctag(p, getcallerpc(&n));
return p;
}
u64int
nanosec(void)
{
static time_t sec0;
struct timespec t;
if(clock_gettime(CLOCK_MONOTONIC, &t) != 0)
fatal("clock_gettime");
if(sec0 == 0)
sec0 = t.tv_sec;
t.tv_sec -= sec0;
return t.tv_sec*1000000000ULL + t.tv_nsec;
}
double
dtime(void)
{
return nanosec()/1000000000.0;
}
void
game_shutdown(void)
{
stopfb();
Host_Shutdown();
exit(0);
}
int
main(int argc, char **argv)
{
double t, t2, dt;
struct parg_state ps;
int c, nargs, i;
static char *paths[8] = {0};
i = 0;
paths[i++] = ".";
paths[i++] = "/usr/games/quake";
paths[i++] = strdup(va("%s/.quake", getenv("HOME")));
parg_init(&ps);
nargs = 0;
while((c = parg_getopt(&ps, argc, argv, "b:Ddg:N:")) >= 0){
switch(c){
case 1:
argv[nargs++] = (char*)ps.optarg;
break;
case 'b':
if(i < nelem(paths)-2)
paths[i++] = (char*)ps.optarg;
break;
case 'N':
if(ndisabled < nelem(disabled))
disabled[ndisabled++] = ps.optarg;
break;
case 'D':
debug++;
break;
case 'd':
dedicated = 1;
break;
case 'g':
game = (char*)ps.optarg;
break;
case 'h':
fprintf(stderr, "usage: qk1 [-g game]\n");
return 0;
break;
case '?':
fprintf(stderr, "unknown option -%c\n", ps.optopt);
return 1;
break;
default:
fprintf(stderr, "unhandled option -%c\n", c);
return 1;
break;
}
}
m_random_init(time(nil));
srand(time(nil));
paths[i] = sys_wrpath();
Host_Init(nargs, argv, paths);
fesetround(FE_TOWARDZERO);
t = dtime() - 1.0 / Fpsmax;
for(;;){
t2 = dtime();
dt = t2 - t;
if(cls.state == ca_dedicated){
if(dt < sys_ticrate.value)
continue;
dt = sys_ticrate.value;
}
if(dt > sys_ticrate.value * 2)
t = t2;
else
t += dt;
Host_Frame(dt);
}
return 0;
}