2004-09-07 18:18:02 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2005-11-03 23:49:00 +00:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
2004-09-07 18:18:02 +00:00
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
//well, linux or cygwin (windows with posix emulation layer), anyway...
# include <unistd.h>
# include <signal.h>
# include <stdlib.h>
# include <limits.h>
2011-07-06 01:01:13 +00:00
# include <time.h>
2004-09-07 18:18:02 +00:00
# include <sys/time.h>
# include <sys/types.h>
# include <unistd.h>
# include <fcntl.h>
# include <stdarg.h>
# include <stdio.h>
2006-05-02 00:56:30 +00:00
# include <dlfcn.h>
2010-01-11 18:15:42 +00:00
# include <dirent.h>
2005-11-03 23:49:00 +00:00
# ifndef __CYGWIN__
2004-09-07 18:18:02 +00:00
# include <sys/ipc.h>
# include <sys/shm.h>
# endif
# include <sys/stat.h>
# include <string.h>
# include <ctype.h>
# include <sys/wait.h>
# include <sys/mman.h>
# include <errno.h>
2007-10-19 18:31:23 +00:00
# ifndef __MACOSX__
2006-04-15 03:44:10 +00:00
# include <X11/Xlib.h>
2007-10-19 18:31:23 +00:00
# endif
2007-12-30 00:09:34 +00:00
# ifdef MULTITHREAD
# include <pthread.h>
# endif
2004-09-07 18:18:02 +00:00
# include "quakedef.h"
# undef malloc
int noconinput = 0 ;
int nostdout = 0 ;
char * basedir = " . " ;
qboolean Sys_InitTerminal ( void ) //we either have one or we don't.
{
return true ;
}
void Sys_CloseTerminal ( void )
{
}
2010-12-05 02:52:41 +00:00
void Sys_RecentServer ( char * command , char * target , char * title , char * desc )
{
}
2004-09-07 18:18:02 +00:00
2005-08-19 14:05:33 +00:00
# ifndef CLIENTONLY
2004-09-07 18:18:02 +00:00
qboolean isDedicated ;
2005-08-19 14:05:33 +00:00
# endif
2004-09-07 18:18:02 +00:00
// =======================================================================
// General routines
// =======================================================================
2011-01-29 19:53:38 +00:00
# if 1
static int ansiremap [ 8 ] = { 0 , 4 , 2 , 6 , 1 , 5 , 3 , 7 } ;
static void ApplyColour ( unsigned int chr )
{
static int oldchar = CON_WHITEMASK ;
int bg , fg ;
chr & = CON_FLAGSMASK ;
if ( oldchar = = chr )
return ;
oldchar = chr ;
printf ( " \ e[0; " ) ; // reset
if ( chr & CON_BLINKTEXT )
printf ( " 5; " ) ; // set blink
bg = ( chr & CON_BGMASK ) > > CON_BGSHIFT ;
fg = ( chr & CON_FGMASK ) > > CON_FGSHIFT ;
// don't handle intensive bit for background
// as terminals differ too much in displaying \e[1;7;3?m
bg & = 0x7 ;
if ( chr & CON_NONCLEARBG )
{
if ( fg & 0x8 ) // intensive bit set for foreground
{
printf ( " 1; " ) ; // set bold/intensity ansi flag
fg & = 0x7 ; // strip intensive bit
}
// set foreground and background colors
printf ( " 3%i;4%im " , ansiremap [ fg ] , ansiremap [ bg ] ) ;
}
else
{
switch ( fg )
{
//to get around wierd defaults (like a white background) we have these special hacks for colours 0 and 7
case COLOR_BLACK :
printf ( " 7m " ) ; // set inverse
break ;
case COLOR_GREY :
printf ( " 1;30m " ) ; // treat as dark grey
break ;
case COLOR_WHITE :
printf ( " m " ) ; // set nothing else
break ;
default :
if ( fg & 0x8 ) // intensive bit set for foreground
{
printf ( " 1; " ) ; // set bold/intensity ansi flag
fg & = 0x7 ; // strip intensive bit
}
printf ( " 3%im " , ansiremap [ fg ] ) ; // set foreground
break ;
}
}
}
# include <wchar.h>
void Sys_Printf ( char * fmt , . . . )
{
va_list argptr ;
char text [ 2048 ] ;
conchar_t ctext [ 2048 ] ;
conchar_t * c , * e ;
wchar_t w ;
if ( nostdout )
return ;
va_start ( argptr , fmt ) ;
2012-07-14 16:36:19 +00:00
vsnprintf ( text , sizeof ( text ) - 1 , fmt , argptr ) ;
2011-01-29 19:53:38 +00:00
va_end ( argptr ) ;
if ( strlen ( text ) > sizeof ( text ) )
Sys_Error ( " memory overwrite in Sys_Printf " ) ;
e = COM_ParseFunString ( CON_WHITEMASK , text , ctext , sizeof ( ctext ) , false ) ;
for ( c = ctext ; c < e ; c + + )
{
2012-10-14 10:53:50 +00:00
if ( * c & CON_HIDDEN )
continue ;
2011-01-29 19:53:38 +00:00
ApplyColour ( * c ) ;
w = * c & 0x0ffff ;
if ( w > = 0xe000 & & w < 0xe100 )
{
2012-10-14 10:53:50 +00:00
/*not all quake chars are ascii compatible, so map those control chars to safe ones so we don't mess up anyone's xterm*/
if ( ( w & 0x7f ) > 0x20 )
putc ( w & 0x7f , stdout ) ;
else if ( w & 0x80 )
{
static char tab [ 32 ] = " ---#@.@@@@ # >.. " " []0123456789.--- " ;
putc ( tab [ w & 31 ] , stdout ) ;
}
else
{
static char tab [ 32 ] = " .####.#### # >.. " " []0123456789.--- " ;
putc ( tab [ w & 31 ] , stdout ) ;
}
2011-01-29 19:53:38 +00:00
}
else
{
/*putwc doesn't like me. force it in utf8*/
if ( w > = 0x80 )
{
if ( w > 0x800 )
{
putc ( 0xe0 | ( ( w > > 12 ) & 0x0f ) , stdout ) ;
putc ( 0x80 | ( ( w > > 6 ) & 0x3f ) , stdout ) ;
}
else
putc ( 0xc0 | ( ( w > > 6 ) & 0x1f ) , stdout ) ;
putc ( 0x80 | ( w & 0x3f ) , stdout ) ;
}
else
putc ( w , stdout ) ;
}
}
ApplyColour ( CON_WHITEMASK ) ;
}
# else
2004-09-07 18:18:02 +00:00
void Sys_Printf ( char * fmt , . . . )
{
va_list argptr ;
char text [ 2048 ] ;
unsigned char * p ;
va_start ( argptr , fmt ) ;
2012-07-14 16:36:19 +00:00
vsnprintf ( text , sizeof ( text ) - 1 , fmt , argptr ) ;
2004-09-07 18:18:02 +00:00
va_end ( argptr ) ;
if ( strlen ( text ) > sizeof ( text ) )
Sys_Error ( " memory overwrite in Sys_Printf " ) ;
2005-08-01 15:08:05 +00:00
if ( nostdout )
return ;
2004-09-07 18:18:02 +00:00
for ( p = ( unsigned char * ) text ; * p ; p + + )
if ( ( * p > 128 | | * p < 32 ) & & * p ! = 10 & & * p ! = 13 & & * p ! = 9 )
printf ( " [%02x] " , * p ) ;
else
putc ( * p , stdout ) ;
}
2011-01-29 19:53:38 +00:00
# endif
2004-09-07 18:18:02 +00:00
void Sys_Quit ( void )
{
Host_Shutdown ( ) ;
2005-08-01 15:08:05 +00:00
fcntl ( 0 , F_SETFL , fcntl ( 0 , F_GETFL , 0 ) & ~ FNDELAY ) ;
2004-09-07 18:18:02 +00:00
exit ( 0 ) ;
}
void Sys_Init ( void )
{
}
2011-04-30 17:21:10 +00:00
void Sys_Shutdown ( void )
{
}
2004-09-07 18:18:02 +00:00
void Sys_Error ( const char * error , . . . )
2005-11-03 23:49:00 +00:00
{
2005-08-01 15:08:05 +00:00
va_list argptr ;
char string [ 1024 ] ;
2004-09-07 18:18:02 +00:00
// change stdin to non blocking
2005-08-01 15:08:05 +00:00
fcntl ( 0 , F_SETFL , fcntl ( 0 , F_GETFL , 0 ) & ~ FNDELAY ) ;
2005-11-03 23:49:00 +00:00
2005-08-01 15:08:05 +00:00
va_start ( argptr , error ) ;
2012-07-14 16:36:19 +00:00
vsnprintf ( string , sizeof ( string ) - 1 , error , argptr ) ;
2005-08-01 15:08:05 +00:00
va_end ( argptr ) ;
2004-09-07 18:18:02 +00:00
fprintf ( stderr , " Error: %s \n " , string ) ;
Host_Shutdown ( ) ;
exit ( 1 ) ;
2005-11-03 23:49:00 +00:00
}
2004-09-07 18:18:02 +00:00
void Sys_Warn ( char * warning , . . . )
2005-11-03 23:49:00 +00:00
{
2005-08-01 15:08:05 +00:00
va_list argptr ;
char string [ 1024 ] ;
2005-11-03 23:49:00 +00:00
2005-08-01 15:08:05 +00:00
va_start ( argptr , warning ) ;
2012-07-14 16:36:19 +00:00
vsnprintf ( string , sizeof ( string ) - 1 , warning , argptr ) ;
2005-08-01 15:08:05 +00:00
va_end ( argptr ) ;
2004-09-07 18:18:02 +00:00
fprintf ( stderr , " Warning: %s " , string ) ;
2005-11-03 23:49:00 +00:00
}
2004-09-07 18:18:02 +00:00
/*
= = = = = = = = = = = =
Sys_FileTime
returns - 1 if not present
= = = = = = = = = = = =
*/
int Sys_FileTime ( char * path )
{
struct stat buf ;
2005-11-03 23:49:00 +00:00
2004-09-07 18:18:02 +00:00
if ( stat ( path , & buf ) = = - 1 )
return - 1 ;
2005-11-03 23:49:00 +00:00
2004-09-07 18:18:02 +00:00
return buf . st_mtime ;
}
void Sys_mkdir ( char * path )
{
2005-08-01 15:08:05 +00:00
mkdir ( path , 0777 ) ;
2004-09-07 18:18:02 +00:00
}
2005-08-01 15:08:05 +00:00
2004-09-07 18:18:02 +00:00
qboolean Sys_remove ( char * path )
{
return system ( va ( " rm \" %s \" " , path ) ) ;
}
2012-04-24 07:59:11 +00:00
qboolean Sys_Rename ( char * oldfname , char * newfname )
{
return ! rename ( oldfname , newfname ) ;
}
2004-09-07 18:18:02 +00:00
int Sys_FileOpenRead ( char * path , int * handle )
{
2005-08-01 15:08:05 +00:00
int h ;
struct stat fileinfo ;
2005-11-03 23:49:00 +00:00
2004-09-07 18:18:02 +00:00
h = open ( path , O_RDONLY , 0666 ) ;
* handle = h ;
if ( h = = - 1 )
return - 1 ;
2005-11-03 23:49:00 +00:00
2004-09-07 18:18:02 +00:00
if ( fstat ( h , & fileinfo ) = = - 1 )
Sys_Error ( " Error fstating %s " , path ) ;
return fileinfo . st_size ;
}
int Sys_FileOpenWrite ( char * path )
{
2005-08-01 15:08:05 +00:00
int handle ;
2004-09-07 18:18:02 +00:00
umask ( 0 ) ;
2005-11-03 23:49:00 +00:00
2005-08-01 15:08:05 +00:00
handle = open ( path , O_RDWR | O_CREAT | O_TRUNC , 0666 ) ;
2004-09-07 18:18:02 +00:00
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 )
{
2005-08-01 15:08:05 +00:00
return read ( handle , dest , count ) ;
2004-09-07 18:18:02 +00:00
}
2005-12-05 16:47:29 +00:00
int Sys_DebugLog ( char * file , char * fmt , . . . )
2004-09-07 18:18:02 +00:00
{
2005-11-03 23:49:00 +00:00
va_list argptr ;
2005-08-01 15:08:05 +00:00
static char data [ 1024 ] ;
int fd ;
2011-05-15 13:23:13 +00:00
size_t result ;
2005-11-03 23:49:00 +00:00
2005-08-01 15:08:05 +00:00
va_start ( argptr , fmt ) ;
2012-07-14 16:36:19 +00:00
vsnprintf ( data , sizeof ( data ) - 1 , fmt , argptr ) ;
2005-08-01 15:08:05 +00:00
va_end ( argptr ) ;
2004-09-07 18:18:02 +00:00
2005-08-01 15:08:05 +00:00
if ( strlen ( data ) > sizeof ( data ) )
Sys_Error ( " Sys_DebugLog's buffer was stomped \n " ) ;
2004-09-07 18:18:02 +00:00
2005-08-01 15:08:05 +00:00
// fd = open(file, O_WRONLY | O_BINARY | O_CREAT | O_APPEND, 0666);
fd = open ( file , O_WRONLY | O_CREAT | O_APPEND , 0666 ) ;
2005-12-05 16:47:29 +00:00
if ( fd )
{
2011-05-15 13:23:13 +00:00
result = write ( fd , data , strlen ( data ) ) ; // do something with result
2011-05-30 04:32:04 +00:00
if ( result ! = strlen ( data ) )
2011-06-01 13:21:54 +00:00
Con_SafePrintf ( " Sys_DebugLog() write: Filename: %s, expected %lu, result was %lu (%s) \n " , file , ( unsigned long ) strlen ( data ) , ( unsigned long ) result , strerror ( errno ) ) ;
2011-05-30 04:32:04 +00:00
2005-12-05 16:47:29 +00:00
close ( fd ) ;
return 0 ;
}
return 1 ;
2004-09-07 18:18:02 +00:00
}
2009-04-02 22:25:54 +00:00
int Sys_EnumerateFiles ( const char * gpath , const char * match , int ( * func ) ( const char * , int , void * ) , void * parm )
2004-09-07 18:18:02 +00:00
{
2010-01-11 18:15:42 +00:00
DIR * dir ;
2004-09-07 18:18:02 +00:00
char apath [ MAX_OSPATH ] ;
char file [ MAX_OSPATH ] ;
char truepath [ MAX_OSPATH ] ;
char * s ;
struct dirent * ent ;
2010-01-11 18:15:42 +00:00
struct stat st ;
2004-09-07 18:18:02 +00:00
//printf("path = %s\n", gpath);
//printf("match = %s\n", match);
if ( ! gpath )
gpath = " " ;
* apath = ' \0 ' ;
Q_strncpyz ( apath , match , sizeof ( apath ) ) ;
for ( s = apath + strlen ( apath ) - 1 ; s > = apath ; s - - )
{
if ( * s = = ' / ' )
{
s [ 1 ] = ' \0 ' ;
match + = s - apath + 1 ;
break ;
}
}
if ( s < apath ) //didn't find a '/'
* apath = ' \0 ' ;
2006-05-19 19:15:52 +00:00
Q_snprintfz ( truepath , sizeof ( truepath ) , " %s/%s " , gpath , apath ) ;
2004-09-07 18:18:02 +00:00
//printf("truepath = %s\n", truepath);
//printf("gamepath = %s\n", gpath);
//printf("apppath = %s\n", apath);
//printf("match = %s\n", match);
dir = opendir ( truepath ) ;
if ( ! dir )
{
2005-11-03 23:49:00 +00:00
Con_DPrintf ( " Failed to open dir %s \n " , truepath ) ;
2004-09-07 18:18:02 +00:00
return true ;
}
do
{
ent = readdir ( dir ) ;
if ( ! ent )
break ;
if ( * ent - > d_name ! = ' . ' )
2010-01-11 18:15:42 +00:00
{
2004-09-07 18:18:02 +00:00
if ( wildcmp ( match , ent - > d_name ) )
{
2010-01-11 18:15:42 +00:00
Q_snprintfz ( file , sizeof ( file ) , " %s/%s " , truepath , ent - > d_name ) ;
2004-09-07 18:18:02 +00:00
2010-01-11 18:15:42 +00:00
if ( stat ( file , & st ) = = 0 )
2004-09-07 18:18:02 +00:00
{
2010-01-11 18:15:42 +00:00
Q_snprintfz ( file , sizeof ( file ) , " %s%s%s " , apath , ent - > d_name , S_ISDIR ( st . st_mode ) ? " / " : " " ) ;
2004-09-07 18:18:02 +00:00
2010-01-11 18:15:42 +00:00
if ( ! func ( file , st . st_size , parm ) )
{
closedir ( dir ) ;
return false ;
}
2004-09-07 18:18:02 +00:00
}
2010-01-11 18:15:42 +00:00
else
printf ( " Stat failed for \" %s \" \n " , file ) ;
2004-09-07 18:18:02 +00:00
}
2010-01-11 18:15:42 +00:00
}
2004-09-07 18:18:02 +00:00
} while ( 1 ) ;
closedir ( dir ) ;
return true ;
}
2005-11-26 03:02:55 +00:00
int secbase ;
2004-09-07 18:18:02 +00:00
double Sys_DoubleTime ( void )
{
2005-08-01 15:08:05 +00:00
struct timeval tp ;
2005-11-03 23:49:00 +00:00
struct timezone tzp ;
gettimeofday ( & tp , & tzp ) ;
2004-09-07 18:18:02 +00:00
2005-08-01 15:08:05 +00:00
if ( ! secbase )
{
secbase = tp . tv_sec ;
return tp . tv_usec / 1000000.0 ;
}
2004-09-07 18:18:02 +00:00
2005-08-01 15:08:05 +00:00
return ( tp . tv_sec - secbase ) + tp . tv_usec / 1000000.0 ;
2004-09-07 18:18:02 +00:00
}
2010-07-12 22:46:37 +00:00
unsigned int Sys_Milliseconds ( void )
{
return Sys_DoubleTime ( ) * 1000 ;
}
2006-05-02 00:56:30 +00:00
static void * game_library ;
void Sys_UnloadGame ( void )
2004-09-07 18:18:02 +00:00
{
2011-05-15 13:23:13 +00:00
if ( game_library )
2006-05-02 00:56:30 +00:00
{
dlclose ( game_library ) ;
game_library = 0 ;
}
2004-09-07 18:18:02 +00:00
}
2005-08-01 15:08:05 +00:00
2006-05-02 00:56:30 +00:00
void * Sys_GetGameAPI ( void * parms )
2004-09-07 18:18:02 +00:00
{
2006-05-02 00:56:30 +00:00
void * ( * GetGameAPI ) ( void * ) ;
char name [ MAX_OSPATH ] ;
2006-05-02 06:13:11 +00:00
char curpath [ MAX_OSPATH ] ;
2006-05-02 00:56:30 +00:00
char * searchpath ;
2011-06-29 18:39:11 +00:00
const char * agamename = " gamei386.so " ;
const char * ggamename = " game.so " ;
2011-05-19 13:34:07 +00:00
char * result ;
2006-05-02 00:56:30 +00:00
void * ret ;
2011-05-15 13:23:13 +00:00
result = getcwd ( curpath , sizeof ( curpath ) ) ; // do something with result?
2010-05-01 22:47:47 +00:00
2011-10-27 15:46:36 +00:00
# ifdef warningmsg
# pragma warningmsg("Search for both gamei386.so and game.so")
# endif
2011-07-01 07:27:38 +00:00
Con_DPrintf ( " Searching for %s but not %s \n " , agamename , ggamename ) ;
2011-05-15 13:23:13 +00:00
2006-05-02 00:56:30 +00:00
searchpath = 0 ;
while ( ( searchpath = COM_NextPath ( searchpath ) ) )
{
2007-01-18 23:17:31 +00:00
if ( searchpath [ 0 ] = = ' / ' )
2011-07-01 07:27:38 +00:00
snprintf ( name , sizeof ( name ) , " %s/%s " , searchpath , agamename ) ;
2007-01-18 23:17:31 +00:00
else
2011-07-01 07:27:38 +00:00
snprintf ( name , sizeof ( name ) , " %s/%s/%s " , curpath , searchpath , agamename ) ;
2006-05-02 06:13:11 +00:00
2012-10-08 05:10:14 +00:00
game_library = dlopen ( name , RTLD_NOW | RTLD_LOCAL ) ;
2006-05-02 00:56:30 +00:00
if ( game_library )
{
GetGameAPI = ( void * ) dlsym ( game_library , " GetGameAPI " ) ;
if ( GetGameAPI & & ( ret = GetGameAPI ( parms ) ) )
{
return ret ;
}
dlclose ( game_library ) ;
game_library = 0 ;
}
}
return 0 ;
2004-09-07 18:18:02 +00:00
}
2008-11-09 22:29:28 +00:00
void Sys_CloseLibrary ( dllhandle_t * lib )
{
2008-11-11 12:20:46 +00:00
dlclose ( ( void * ) lib ) ;
2008-11-09 22:29:28 +00:00
}
2011-01-27 01:34:08 +00:00
2009-11-05 03:07:52 +00:00
dllhandle_t * Sys_LoadLibrary ( const char * name , dllfunction_t * funcs )
2008-11-09 22:29:28 +00:00
{
int i ;
2008-11-11 10:09:41 +00:00
dllhandle_t lib ;
2008-11-09 22:29:28 +00:00
2011-01-29 19:53:38 +00:00
lib = NULL ;
if ( ! lib )
lib = dlopen ( name , RTLD_LAZY ) ;
2012-10-08 01:30:41 +00:00
if ( ! lib & & strcmp ( COM_FileExtension ( name ) , " so " ) )
2011-01-29 19:53:38 +00:00
lib = dlopen ( va ( " %s.so " , name ) , RTLD_LAZY ) ;
2008-11-09 22:29:28 +00:00
if ( ! lib )
2012-10-08 01:30:41 +00:00
{
2012-10-08 05:10:14 +00:00
Con_DPrintf ( " %s \n " , dlerror ( ) ) ;
2008-11-09 22:29:28 +00:00
return NULL ;
2012-10-08 01:30:41 +00:00
}
2008-11-09 22:29:28 +00:00
2011-05-30 21:48:32 +00:00
if ( funcs )
2008-11-09 22:29:28 +00:00
{
2011-05-30 21:48:32 +00:00
for ( i = 0 ; funcs [ i ] . name ; i + + )
{
* funcs [ i ] . funcptr = dlsym ( lib , funcs [ i ] . name ) ;
if ( ! * funcs [ i ] . funcptr )
break ;
}
if ( funcs [ i ] . name )
{
2012-10-08 01:30:41 +00:00
Con_DPrintf ( " Unable to find symbol \" %s \" in \" %s \" \n " , funcs [ i ] . name , name ) ;
2011-05-30 21:48:32 +00:00
Sys_CloseLibrary ( ( dllhandle_t * ) lib ) ;
lib = NULL ;
}
2008-11-09 22:29:28 +00:00
}
return ( dllhandle_t * ) lib ;
}
2011-05-30 21:48:32 +00:00
void * Sys_GetAddressForName ( dllhandle_t * module , const char * exportname )
{
if ( ! module )
return NULL ;
return dlsym ( module , exportname ) ;
}
2004-09-07 18:18:02 +00:00
// =======================================================================
// Sleeps for microseconds
// =======================================================================
static volatile int oktogo ;
void alarm_handler ( int x )
{
oktogo = 1 ;
}
char * Sys_ConsoleInput ( void )
{
#if 0
2005-08-01 15:08:05 +00:00
static char text [ 256 ] ;
int len ;
2004-09-07 18:18:02 +00:00
2005-08-01 15:08:05 +00:00
if ( cls . state = = ca_dedicated )
{
2004-09-07 18:18:02 +00:00
len = read ( 0 , text , sizeof ( text ) ) ;
if ( len < 1 )
return NULL ;
2005-08-01 15:08:05 +00:00
2004-09-07 18:18:02 +00:00
text [ len - 1 ] = 0 ; // rip off the /n and terminate
return text ;
}
# endif
return NULL ;
}
2011-05-19 13:34:07 +00:00
int main ( int c , const char * * v )
2004-09-07 18:18:02 +00:00
{
2005-08-01 15:08:05 +00:00
double time , oldtime , newtime ;
2004-09-07 18:18:02 +00:00
quakeparms_t parms ;
int j ;
// static char cwd[1024];
signal ( SIGFPE , SIG_IGN ) ;
2006-03-17 22:44:17 +00:00
signal ( SIGPIPE , SIG_IGN ) ;
2004-09-07 18:18:02 +00:00
memset ( & parms , 0 , sizeof ( parms ) ) ;
2010-07-11 10:53:13 +00:00
parms . argc = c ;
parms . argv = v ;
COM_InitArgv ( parms . argc , parms . argv ) ;
2004-09-07 18:18:02 +00:00
TL_InitLanguages ( ) ;
2012-01-21 07:53:49 +00:00
parms . memsize = 64 * 1024 * 1024 ;
2004-09-07 18:18:02 +00:00
j = COM_CheckParm ( " -mem " ) ;
2004-12-24 08:45:56 +00:00
if ( j & & j + 1 < com_argc )
2004-09-07 18:18:02 +00:00
parms . memsize = ( int ) ( Q_atof ( com_argv [ j + 1 ] ) * 1024 * 1024 ) ;
2005-08-01 15:08:05 +00:00
2004-09-07 18:18:02 +00:00
parms . membase = malloc ( parms . memsize ) ;
parms . basedir = basedir ;
noconinput = COM_CheckParm ( " -noconinput " ) ;
if ( ! noconinput )
fcntl ( 0 , F_SETFL , fcntl ( 0 , F_GETFL , 0 ) | FNDELAY ) ;
if ( COM_CheckParm ( " -nostdout " ) )
nostdout = 1 ;
2005-08-01 15:08:05 +00:00
Host_Init ( & parms ) ;
2004-09-07 18:18:02 +00:00
2005-08-01 15:08:05 +00:00
oldtime = Sys_DoubleTime ( ) ;
while ( 1 )
{
2011-07-06 01:01:13 +00:00
double sleeptime ;
2007-09-23 22:00:19 +00:00
# ifdef __MACOSX__
//wow, not even windows was this absurd.
# ifdef RGLQUAKE
if ( glcocoaRunLoop ( ) )
{
oldtime = Sys_DoubleTime ( ) ;
continue ;
}
# endif
# endif
2004-09-07 18:18:02 +00:00
// find time spent rendering last frame
2005-08-01 15:08:05 +00:00
newtime = Sys_DoubleTime ( ) ;
time = newtime - oldtime ;
2004-09-07 18:18:02 +00:00
2011-07-06 01:01:13 +00:00
sleeptime = Host_Frame ( time ) ;
2004-09-07 18:18:02 +00:00
oldtime = newtime ;
2011-07-06 01:01:13 +00:00
Sys_Sleep ( sleeptime ) ;
2005-08-01 15:08:05 +00:00
}
2004-09-07 18:18:02 +00:00
}
/*
= = = = = = = = = = = = = = = =
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 " ) ;
}
2004-09-07 19:07:37 +00:00
//fixme: some sort of taskbar/gnome panel flashing.
void Sys_ServerActivity ( void )
{
}
2006-04-15 03:31:23 +00:00
//FIXME: this is hacky. Unlike other OSes where the GUI is part of the OS, X is seperate
//from the OS. This will cause problems with framebuffer-only setups.
qboolean Sys_GetDesktopParameters ( int * width , int * height , int * bpp , int * refreshrate )
{
2007-09-22 19:28:27 +00:00
# ifdef __MACOSX__
//this about sums up the problem with this function
return false ;
# else
2006-04-15 03:31:23 +00:00
Display * xtemp ;
int scr ;
2011-05-15 13:23:13 +00:00
2006-04-15 03:31:23 +00:00
xtemp = XOpenDisplay ( NULL ) ;
if ( ! xtemp )
return false ;
scr = DefaultScreen ( xtemp ) ;
2006-02-01 22:36:12 +00:00
2006-04-15 03:31:23 +00:00
* width = DisplayWidth ( xtemp , scr ) ;
* height = DisplayHeight ( xtemp , scr ) ;
* bpp = DefaultDepth ( xtemp , scr ) ;
* refreshrate = 0 ;
2006-02-01 22:36:12 +00:00
2006-04-15 03:31:23 +00:00
XCloseDisplay ( xtemp ) ;
return true ;
2007-09-22 19:28:27 +00:00
# endif
2006-04-15 03:31:23 +00:00
}
2006-03-11 03:12:10 +00:00
# define SYS_CLIPBOARD_SIZE 256
static char clipboard_buffer [ SYS_CLIPBOARD_SIZE ] = { 0 } ;
char * Sys_GetClipboard ( void ) {
return clipboard_buffer ;
2006-02-01 22:36:12 +00:00
}
2006-03-11 03:12:10 +00:00
2006-02-01 22:36:12 +00:00
void Sys_CloseClipboard ( char * bf )
{
}
2006-03-11 03:12:10 +00:00
void Sys_SaveClipboard ( char * text ) {
Q_strncpyz ( clipboard_buffer , text , SYS_CLIPBOARD_SIZE ) ;
2006-02-12 23:55:40 +00:00
}
2007-12-30 00:09:34 +00:00
# ifdef MULTITHREAD
/* Thread creation calls */
typedef void * ( * pfunction_t ) ( void * ) ;
2012-11-29 13:37:48 +00:00
void * Sys_CreateThread ( char * name , int ( * func ) ( void * ) , void * args , int priority , int stacksize )
2007-12-30 00:09:34 +00:00
{
2007-12-30 20:05:49 +00:00
pthread_t * thread ;
2007-12-30 00:09:34 +00:00
pthread_attr_t attr ;
2011-05-15 13:23:13 +00:00
2007-12-30 20:05:49 +00:00
thread = ( pthread_t * ) malloc ( sizeof ( pthread_t ) ) ;
if ( ! thread )
return NULL ;
2011-05-15 13:23:13 +00:00
2007-12-30 00:09:34 +00:00
pthread_attr_init ( & attr ) ;
2007-12-30 20:05:49 +00:00
pthread_attr_setdetachstate ( & attr , PTHREAD_CREATE_JOINABLE ) ;
2007-12-30 00:09:34 +00:00
if ( stacksize < PTHREAD_STACK_MIN )
stacksize = PTHREAD_STACK_MIN ;
pthread_attr_setstacksize ( & attr , stacksize ) ;
2007-12-30 20:05:49 +00:00
if ( pthread_create ( thread , & attr , ( pfunction_t ) func , args ) )
{
free ( thread ) ;
thread = NULL ;
}
pthread_attr_destroy ( & attr ) ;
return ( void * ) thread ;
}
2007-12-30 00:09:34 +00:00
2007-12-30 20:05:49 +00:00
void Sys_WaitOnThread ( void * thread )
{
2011-05-15 13:23:13 +00:00
pthread_join ( ( pthread_t * ) thread , NULL ) ;
2007-12-30 20:05:49 +00:00
free ( thread ) ;
2007-12-30 00:09:34 +00:00
}
/* Mutex calls */
2008-06-01 05:42:23 +00:00
void * Sys_CreateMutex ( void )
2007-12-30 00:09:34 +00:00
{
pthread_mutex_t * mutex = ( pthread_mutex_t * ) malloc ( sizeof ( pthread_mutex_t ) ) ;
2011-05-15 13:23:13 +00:00
2007-12-30 00:09:34 +00:00
if ( mutex & & ! pthread_mutex_init ( mutex , NULL ) )
return mutex ;
return NULL ;
}
qboolean Sys_TryLockMutex ( void * mutex )
{
return ! pthread_mutex_trylock ( mutex ) ;
}
qboolean Sys_LockMutex ( void * mutex )
{
return ! pthread_mutex_lock ( mutex ) ;
}
qboolean Sys_UnlockMutex ( void * mutex )
{
return ! pthread_mutex_unlock ( mutex ) ;
}
void Sys_DestroyMutex ( void * mutex )
{
pthread_mutex_destroy ( mutex ) ;
free ( mutex ) ;
}
2008-06-01 05:42:23 +00:00
/* Conditional wait calls */
typedef struct condvar_s
{
pthread_mutex_t * mutex ;
pthread_cond_t * cond ;
} condvar_t ;
void * Sys_CreateConditional ( void )
{
condvar_t * condv ;
pthread_mutex_t * mutex ;
pthread_cond_t * cond ;
2011-05-15 13:23:13 +00:00
2008-06-01 05:42:23 +00:00
condv = ( condvar_t * ) malloc ( sizeof ( condvar_t ) ) ;
if ( ! condv )
return NULL ;
2011-05-15 13:23:13 +00:00
2008-06-01 05:42:23 +00:00
mutex = ( pthread_mutex_t * ) malloc ( sizeof ( pthread_mutex_t ) ) ;
if ( ! mutex )
return NULL ;
2011-05-15 13:23:13 +00:00
2008-06-01 05:42:23 +00:00
cond = ( pthread_cond_t * ) malloc ( sizeof ( pthread_cond_t ) ) ;
if ( ! cond )
return NULL ;
2011-05-15 13:23:13 +00:00
2008-06-01 05:42:23 +00:00
if ( ! pthread_mutex_init ( mutex , NULL ) )
{
if ( ! pthread_cond_init ( cond , NULL ) )
{
condv - > cond = cond ;
condv - > mutex = mutex ;
2011-05-15 13:23:13 +00:00
2008-06-01 05:42:23 +00:00
return ( void * ) condv ;
}
else
pthread_mutex_destroy ( mutex ) ;
}
2011-05-15 13:23:13 +00:00
2008-06-01 05:42:23 +00:00
free ( cond ) ;
free ( mutex ) ;
free ( condv ) ;
2011-05-15 13:23:13 +00:00
return NULL ;
2008-06-01 05:42:23 +00:00
}
qboolean Sys_LockConditional ( void * condv )
{
return ! pthread_mutex_lock ( ( ( condvar_t * ) condv ) - > mutex ) ;
}
qboolean Sys_UnlockConditional ( void * condv )
{
return ! pthread_mutex_unlock ( ( ( condvar_t * ) condv ) - > mutex ) ;
}
qboolean Sys_ConditionWait ( void * condv )
{
return ! pthread_cond_wait ( ( ( condvar_t * ) condv ) - > cond , ( ( condvar_t * ) condv ) - > mutex ) ;
}
qboolean Sys_ConditionSignal ( void * condv )
{
return ! pthread_cond_signal ( ( ( condvar_t * ) condv ) - > cond ) ;
}
qboolean Sys_ConditionBroadcast ( void * condv )
{
return ! pthread_cond_broadcast ( ( ( condvar_t * ) condv ) - > cond ) ;
}
void Sys_DestroyConditional ( void * condv )
{
condvar_t * cv = ( condvar_t * ) condv ;
2011-05-15 13:23:13 +00:00
2008-06-01 05:42:23 +00:00
pthread_cond_destroy ( cv - > cond ) ;
pthread_mutex_destroy ( cv - > mutex ) ;
free ( cv - > cond ) ;
free ( cv - > mutex ) ;
free ( cv ) ;
}
2011-07-06 01:01:13 +00:00
# endif
2011-07-03 16:24:53 +00:00
2011-07-06 01:01:13 +00:00
void Sys_Sleep ( double seconds )
2011-07-03 16:24:53 +00:00
{
2011-07-06 01:01:13 +00:00
struct timespec ts ;
ts . tv_sec = ( time_t ) seconds ;
seconds - = ts . tv_sec ;
ts . tv_nsec = seconds * 1000000000.0 ;
nanosleep ( & ts , NULL ) ;
2011-07-03 16:24:53 +00:00
}
2011-07-31 11:18:49 +00:00
qboolean Sys_RandomBytes ( qbyte * string , int len )
{
qboolean res ;
int fd = open ( " /dev/urandom " , 0 ) ;
res = ( read ( fd , string , len ) = = len ) ;
close ( fd ) ;
return res ;
}