/* * Copyright (C) 1997-2001 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 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * 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. * * ======================================================================= * * This file implements all system dependend generic funktions * * ======================================================================= */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../common/header/common.h" #include "../common/header/glob.h" #include "header/unix.h" unsigned sys_frame_time; int curtime; static void *game_library; static char findbase [ MAX_OSPATH ]; static char findpath [ MAX_OSPATH ]; static char findpattern [ MAX_OSPATH ]; static DIR *fdir; qboolean stdin_active = true; extern cvar_t *nostdout; extern FILE *logfile; static qboolean CompareAttributes ( char *path, char *name, unsigned musthave, unsigned canthave ) { struct stat st; char fn [ MAX_OSPATH ]; /* . and .. never match */ if ( ( strcmp( name, "." ) == 0 ) || ( strcmp( name, ".." ) == 0 ) ) { return ( false ); } return ( true ); if ( stat( fn, &st ) == -1 ) { return ( false ); /* shouldn't happen */ } if ( ( st.st_mode & S_IFDIR ) && ( canthave & SFF_SUBDIR ) ) { return ( false ); } if ( ( musthave & SFF_SUBDIR ) && !( st.st_mode & S_IFDIR ) ) { return ( false ); } return ( true ); } void Sys_Init ( void ) { } int Sys_Milliseconds ( void ) { struct timeval tp; struct timezone tzp; static int secbase; gettimeofday( &tp, &tzp ); if ( !secbase ) { secbase = tp.tv_sec; return ( tp.tv_usec / 1000 ); } curtime = ( tp.tv_sec - secbase ) * 1000 + tp.tv_usec / 1000; return ( curtime ); } void Sys_Mkdir ( char *path ) { mkdir( path, 0755 ); } char * Sys_GetCurrentDirectory ( void ) { static char dir [ MAX_OSPATH ]; if ( !getcwd( dir, sizeof ( dir ) ) ) { Sys_Error( "Couldn't get current working directory" ); } return ( dir ); } char * Sys_FindFirst ( char *path, unsigned musthave, unsigned canhave ) { struct dirent *d; char *p; if ( fdir ) { Sys_Error( "Sys_BeginFind without close" ); } strcpy( findbase, path ); if ( ( p = strrchr( findbase, '/' ) ) != NULL ) { *p = 0; strcpy( findpattern, p + 1 ); } else { strcpy( findpattern, "*" ); } if ( strcmp( findpattern, "*.*" ) == 0 ) { strcpy( findpattern, "*" ); } if ( ( fdir = opendir( findbase ) ) == NULL ) { return ( NULL ); } while ( ( d = readdir( fdir ) ) != NULL ) { if ( !*findpattern || glob_match( findpattern, d->d_name ) ) { if ( CompareAttributes( findbase, d->d_name, musthave, canhave ) ) { sprintf( findpath, "%s/%s", findbase, d->d_name ); return ( findpath ); } } } return ( NULL ); } char * Sys_FindNext ( unsigned musthave, unsigned canhave ) { struct dirent *d; if ( fdir == NULL ) { return ( NULL ); } while ( ( d = readdir( fdir ) ) != NULL ) { if ( !*findpattern || glob_match( findpattern, d->d_name ) ) { if ( CompareAttributes( findbase, d->d_name, musthave, canhave ) ) { sprintf( findpath, "%s/%s", findbase, d->d_name ); return ( findpath ); } } } return ( NULL ); } void Sys_FindClose ( void ) { if ( fdir != NULL ) { closedir( fdir ); } fdir = NULL; } void Sys_ConsoleOutput ( char *string ) { if ( nostdout && nostdout->value ) { return; } fputs( string, stdout ); } void Sys_Printf ( char *fmt, ... ) { va_list argptr; char text [ 1024 ]; unsigned char *p; va_start( argptr, fmt ); vsnprintf( text, 1024, fmt, argptr ); va_end( argptr ); if ( nostdout && nostdout->value ) { 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 ); } } } void Sys_Quit ( void ) { #ifndef DEDICATED_ONLY CL_Shutdown(); #endif if (logfile) { fclose (logfile); logfile = NULL; } Qcommon_Shutdown(); fcntl( 0, F_SETFL, fcntl( 0, F_GETFL, 0 ) & ~FNDELAY ); printf("------------------------------------\n"); exit( 0 ); } 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 ); #ifndef DEDICATED_ONLY CL_Shutdown(); #endif Qcommon_Shutdown(); va_start( argptr, error ); vsnprintf( string, 1024, error, argptr ); va_end( argptr ); fprintf( stderr, "Error: %s\n", string ); exit( 1 ); } void Sys_Warn ( char *warning, ... ) { va_list argptr; char string [ 1024 ]; va_start( argptr, warning ); vsnprintf( string, 1024, warning, argptr ); va_end( argptr ); fprintf( stderr, "Warning: %s", string ); } /* * 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 floating_point_exception_handler ( int whatever ) { signal( SIGFPE, floating_point_exception_handler ); } char * Sys_ConsoleInput ( void ) { static char text [ 256 ]; int len; fd_set fdset; struct timeval timeout; if ( !dedicated || !dedicated->value ) { return ( NULL ); } if ( !stdin_active ) { return ( NULL ); } 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 == 0 ) /* eof! */ { stdin_active = false; return ( NULL ); } if ( len < 1 ) { return ( NULL ); } text [ len - 1 ] = 0; /* rip off the /n and terminate */ return ( text ); } void Sys_UnloadGame ( void ) { if ( game_library ) { dlclose( game_library ); } game_library = NULL; } /* * Loads the game dll */ void * Sys_GetGameAPI ( void *parms ) { void *( *GetGameAPI )(void *); FILE *fp; char name [ MAX_OSPATH ]; char *path; char *str_p; const char *gamename = "game.so"; setreuid( getuid(), getuid() ); setegid( getgid() ); if ( game_library ) { Com_Error( ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame" ); } Com_Printf( "LoadLibrary(\"%s\")\n", gamename ); /* now run through the search paths */ path = NULL; while ( 1 ) { path = FS_NextPath( path ); if ( !path ) { return ( NULL ); /* couldn't find one anywhere */ } snprintf( name, MAX_OSPATH, "%s/%s", path, gamename ); /* skip it if it just doesn't exist */ fp = fopen( name, "rb" ); if ( fp == NULL ) { continue; } fclose( fp ); game_library = dlopen( name, RTLD_NOW ); if ( game_library ) { Com_MDPrintf( "LoadLibrary (%s)\n", name ); break; } else { Com_Printf( "LoadLibrary (%s):", name ); path = (char *) dlerror(); str_p = strchr( path, ':' ); /* skip the path (already shown) */ if ( str_p == NULL ) { str_p = path; } else { str_p++; } Com_Printf( "%s\n", str_p ); return ( NULL ); } } GetGameAPI = (void *) dlsym( game_library, "GetGameAPI" ); if ( !GetGameAPI ) { Sys_UnloadGame(); return ( NULL ); } return ( GetGameAPI( parms ) ); } void Sys_SendKeyEvents ( void ) { #ifndef DEDICATED_ONLY if ( IN_Update_fp ) { IN_Update_fp(); } #endif /* grab frame time */ sys_frame_time = Sys_Milliseconds(); }