2014-04-12 12:19:49 +00:00
# include <unistd.h>
# include <signal.h>
# include <stdlib.h>
# include <limits.h>
# include <sys/time.h>
# include <sys/types.h>
# include <unistd.h>
# include <fcntl.h>
# include <stdarg.h>
# include <stdio.h>
# include <sys/ipc.h>
# include <sys/shm.h>
# include <sys/stat.h>
# include <string.h>
# include <ctype.h>
# include <sys/wait.h>
# include <sys/mman.h>
# include <errno.h>
# include "quakedef.h"
qboolean isDedicated ;
int nostdout = 0 ;
char * basedir = " . " ;
char * cachedir = " /tmp " ;
// =======================================================================
// 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 ( nostdout )
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_Printf ( char * fmt , . . . )
{
va_list argptr ;
char text [ 1024 ] ;
unsigned char * p ;
va_start ( argptr , fmt ) ;
vsprintf ( text , fmt , argptr ) ;
va_end ( argptr ) ;
if ( strlen ( text ) > sizeof ( text ) )
Sys_Error ( " memory overwrite in Sys_Printf " ) ;
if ( nostdout )
return ;
for ( p = ( unsigned char * ) text ; * p ; p + + ) {
* p & = 0x7f ;
if ( ( * p > 128 | | * p < 32 ) & & * p ! = 10 & & * p ! = 13 & & * p ! = 9 )
printf ( " [%02x] " , * p ) ;
else
putc ( * p , stdout ) ;
}
fflush ( stdout ) ; // 2000-07-11 Piped output of a dedicated server not written immediately fix by Hendrik Lipka
}
2015-07-23 22:34:51 +00:00
2014-04-12 12:19:49 +00:00
static char end1 [ ] =
" \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 " ;
2015-07-24 18:59:47 +00:00
static char end2 [ ] = " \x1b [0;1;46m \x1b [1;1H \
ENGOO \ x1b [ 37 mversion 2.78 \ n \
\ x1b [ 33 m = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = \ n \
\ n \
\ x1b [ 37 mBased on QIP Engine by Maddes \ n \
\ n \
\ n \
\ x1b [ 33 mProgramming by Linux port by \ n \
\ x1b [ 37 mleilei eukara \ n \
\ n \
\ x1b [ 33 mLOTS of HELP from \ n \
\ x1b [ 37 mLordHavoc - Lighting \ n \
Spike - Memory \ n \
Fitz - Fog \ n \
Qbism - Optimizations \ n \
Mankrip - Optimizations \ n \
Andrewj - Dithering \ n \
Tomaz - Snow / Rain and Bots \ n \
MH - Vid code / interpolation \ n \
Siggi - 2 D Scaling \ n \
Taniwha - Aspect \ n \
\ x1b [ 33 m This engine is licensed under the \ n \
GNU GPL v2 . Read COPYING for more . \ n \ e [ 0 m " ;
2014-04-12 12:19:49 +00:00
2015-07-23 22:34:51 +00:00
2014-04-12 12:19:49 +00:00
void Sys_Quit ( void )
{
Host_Shutdown ( ) ;
2015-07-23 22:34:51 +00:00
fcntl ( 0 , F_SETFL , fcntl ( 0 , F_GETFL , 0 ) & ~ FNDELAY ) ;
2014-04-12 12:19:49 +00:00
if ( registered - > value )
printf ( " %s " , end2 ) ;
else
printf ( " %s " , end1 ) ;
2015-07-23 22:34:51 +00:00
2014-04-12 12:19:49 +00:00
fflush ( stdout ) ;
exit ( 0 ) ;
}
void Sys_Init ( void )
{
# if id386
Sys_SetFPCW ( ) ;
# endif
}
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 ;
}
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 ;
fd_set fdset ;
struct timeval timeout ;
if ( cls . state = = ca_dedicated ) {
FD_ZERO ( & fdset ) ;
FD_SET ( 0 , & fdset ) ; // stdin
timeout . tv_sec = 0 ;
timeout . tv_usec = 0 ;
if ( select ( 1 , & fdset , NULL , NULL , & timeout ) = = - 1 | | ! FD_ISSET ( 0 , & fdset ) )
return NULL ;
len = read ( 0 , text , sizeof ( text ) ) ;
if ( len < 1 )
return NULL ;
text [ len - 1 ] = 0 ; // rip off the /n and terminate
return text ;
}
return NULL ;
}
# if !id386
void Sys_HighFPPrecision ( void )
{
}
void Sys_LowFPPrecision ( void )
{
}
# endif
2015-07-23 22:34:51 +00:00
void VID_CreateSplash ( void ) ;
2014-04-12 12:19:49 +00:00
int main ( int c , char * * v )
{
double time , oldtime , newtime ;
quakeparms_t parms ;
extern int vcrFile ;
extern int recording ;
int j ;
// static char cwd[1024];
// signal(SIGFPE, floating_point_exception_handler);
signal ( SIGFPE , SIG_IGN ) ;
memset ( & parms , 0 , sizeof ( parms ) ) ;
COM_InitArgv ( c , v ) ;
parms . argc = com_argc ;
parms . argv = com_argv ;
# ifdef GLQUAKE
parms . memsize = 16 * 1024 * 1024 ;
# else
2015-07-22 14:11:31 +00:00
parms . memsize = 20 * 1024 * 1024 ;
2014-04-12 12:19:49 +00:00
# endif
j = COM_CheckParm ( " -mem " ) ;
if ( j )
parms . memsize = ( int ) ( Q_atof ( com_argv [ j + 1 ] ) * 1024 * 1024 ) ;
parms . membase = malloc ( parms . memsize ) ;
parms . basedir = basedir ;
// caching is disabled by default, use -cachedir to enable
// parms.cachedir = cachedir;
fcntl ( 0 , F_SETFL , fcntl ( 0 , F_GETFL , 0 ) | FNDELAY ) ;
2015-07-23 22:34:51 +00:00
VID_CreateSplash ( ) ;
Host_Init ( & parms ) ;
2014-04-12 12:19:49 +00:00
Sys_Init ( ) ;
if ( COM_CheckParm ( " -nostdout " ) )
nostdout = 1 ;
else {
fcntl ( 0 , F_SETFL , fcntl ( 0 , F_GETFL , 0 ) | FNDELAY ) ;
printf ( " Linux Quake -- Version %0.3f \n " , LINUX_VERSION ) ;
}
oldtime = Sys_FloatTime ( ) - 0.1 ;
while ( 1 )
{
// 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 ;
Host_Frame ( time ) ;
}
}
/*
= = = = = = = = = = = = = = = =
Sys_MakeCodeWriteable
= = = = = = = = = = = = = = = =
*/
void Sys_MakeCodeWriteable ( unsigned long startaddr , unsigned long length )
{
int r ;
unsigned long addr ;
int psize = getpagesize ( ) ;
addr = ( startaddr & ~ ( psize - 1 ) ) - psize ;
// fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
// addr, startaddr+length, length);
r = mprotect ( ( char * ) addr , length + startaddr - addr + psize , 7 ) ;
if ( r < 0 )
Sys_Error ( " Protection change failed \n " ) ;
}