00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <unistd.h>
00023 #include <signal.h>
00024 #include <stdlib.h>
00025 #include <limits.h>
00026 #include <sys/time.h>
00027 #include <sys/types.h>
00028 #include <unistd.h>
00029 #include <fcntl.h>
00030 #include <stdarg.h>
00031 #include <stdio.h>
00032 #include <sys/ipc.h>
00033 #include <sys/shm.h>
00034 #include <sys/stat.h>
00035 #include <string.h>
00036 #include <ctype.h>
00037 #include <sys/wait.h>
00038 #include <sys/mman.h>
00039 #include <errno.h>
00040 #ifdef __linux__ // rb010123
00041 #include <mntent.h>
00042 #endif
00043 #include <dlfcn.h>
00044
00045 #ifdef __linux__
00046 #include <fpu_control.h>
00047 #endif
00048
00049
00050 #include <termios.h>
00051
00052 #include "../game/q_shared.h"
00053 #include "../qcommon/qcommon.h"
00054 #include "../renderer/tr_public.h"
00055
00056 #include "linux_local.h"
00057
00058
00059 refexport_t re;
00060
00061 unsigned sys_frame_time;
00062
00063 uid_t saved_euid;
00064 qboolean stdin_active = qtrue;
00065
00066
00067
00068
00069
00070
00071
00072 static cvar_t *ttycon = NULL;
00073
00074 static qboolean ttycon_on = qfalse;
00075
00076
00077
00078 static int ttycon_hide = 0;
00079
00080
00081 static int tty_erase;
00082 static int tty_eof;
00083
00084 static struct termios tty_tc;
00085
00086 static field_t tty_con;
00087
00088
00089
00090
00091 #define TTY_HISTORY 32
00092 static field_t ttyEditLines[TTY_HISTORY];
00093 static int hist_current = -1, hist_count = 0;
00094
00095
00096
00097
00098
00099
00100 #define MEM_THRESHOLD 96*1024*1024
00101
00102
00103
00104
00105
00106
00107 qboolean Sys_LowPhysicalMemory() {
00108
00109
00110
00111 return qfalse;
00112 }
00113
00114
00115
00116
00117
00118
00119 int Sys_FunctionCmp(void *f1, void *f2) {
00120 return qtrue;
00121 }
00122
00123
00124
00125
00126
00127
00128 int Sys_FunctionCheckSum(void *f1) {
00129 return 0;
00130 }
00131
00132
00133
00134
00135
00136
00137 int Sys_MonkeyShouldBeSpanked( void ) {
00138 return 0;
00139 }
00140
00141 void Sys_BeginProfiling( void ) {
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151 void Sys_In_Restart_f( void )
00152 {
00153 IN_Shutdown();
00154 IN_Init();
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 void tty_FlushIn()
00166 {
00167 char key;
00168 while (read(0, &key, 1)!=-1);
00169 }
00170
00171
00172
00173
00174
00175 void tty_Back()
00176 {
00177 char key;
00178 key = '\b';
00179 write(1, &key, 1);
00180 key = ' ';
00181 write(1, &key, 1);
00182 key = '\b';
00183 write(1, &key, 1);
00184 }
00185
00186
00187
00188 void tty_Hide()
00189 {
00190 int i;
00191 assert(ttycon_on);
00192 if (ttycon_hide)
00193 {
00194 ttycon_hide++;
00195 return;
00196 }
00197 if (tty_con.cursor>0)
00198 {
00199 for (i=0; i<tty_con.cursor; i++)
00200 {
00201 tty_Back();
00202 }
00203 }
00204 ttycon_hide++;
00205 }
00206
00207
00208
00209 void tty_Show()
00210 {
00211 int i;
00212 assert(ttycon_on);
00213 assert(ttycon_hide>0);
00214 ttycon_hide--;
00215 if (ttycon_hide == 0)
00216 {
00217 if (tty_con.cursor)
00218 {
00219 for (i=0; i<tty_con.cursor; i++)
00220 {
00221 write(1, tty_con.buffer+i, 1);
00222 }
00223 }
00224 }
00225 }
00226
00227
00228 void Sys_ConsoleInputShutdown()
00229 {
00230 if (ttycon_on)
00231 {
00232 Com_Printf("Shutdown tty console\n");
00233 tcsetattr (0, TCSADRAIN, &tty_tc);
00234 }
00235 }
00236
00237 void Hist_Add(field_t *field)
00238 {
00239 int i;
00240 assert(hist_count <= TTY_HISTORY);
00241 assert(hist_count >= 0);
00242 assert(hist_current >= -1);
00243 assert(hist_current <= hist_count);
00244
00245 for (i=TTY_HISTORY-1; i>0; i--)
00246 {
00247 ttyEditLines[i] = ttyEditLines[i-1];
00248 }
00249 ttyEditLines[0] = *field;
00250 if (hist_count<TTY_HISTORY)
00251 {
00252 hist_count++;
00253 }
00254 hist_current = -1;
00255 }
00256
00257 field_t *Hist_Prev()
00258 {
00259 int hist_prev;
00260 assert(hist_count <= TTY_HISTORY);
00261 assert(hist_count >= 0);
00262 assert(hist_current >= -1);
00263 assert(hist_current <= hist_count);
00264 hist_prev = hist_current + 1;
00265 if (hist_prev >= hist_count)
00266 {
00267 return NULL;
00268 }
00269 hist_current++;
00270 return &(ttyEditLines[hist_current]);
00271 }
00272
00273 field_t *Hist_Next()
00274 {
00275 assert(hist_count <= TTY_HISTORY);
00276 assert(hist_count >= 0);
00277 assert(hist_current >= -1);
00278 assert(hist_current <= hist_count);
00279 if (hist_current >= 0)
00280 {
00281 hist_current--;
00282 }
00283 if (hist_current == -1)
00284 {
00285 return NULL;
00286 }
00287 return &(ttyEditLines[hist_current]);
00288 }
00289
00290
00291
00292
00293
00294 #if 0
00295
00296 void Sys_Printf (char *fmt, ...)
00297 {
00298 va_list argptr;
00299 char text[1024];
00300 unsigned char *p;
00301
00302 va_start (argptr,fmt);
00303 vsprintf (text,fmt,argptr);
00304 va_end (argptr);
00305
00306 if (strlen(text) > sizeof(text))
00307 Sys_Error("memory overwrite in Sys_Printf");
00308
00309 for (p = (unsigned char *)text; *p; p++)
00310 {
00311 *p &= 0x7f;
00312 if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
00313 printf("[%02x]", *p);
00314 else
00315 putc(*p, stdout);
00316 }
00317 }
00318 #endif
00319
00320
00321 void Sys_Exit( int ex ) {
00322 Sys_ConsoleInputShutdown();
00323
00324 #ifdef NDEBUG // regular behavior
00325
00326
00327
00328
00329 _exit(ex);
00330 #else
00331
00332
00333 assert( ex == 0 );
00334 exit(ex);
00335 #endif
00336 }
00337
00338
00339 void Sys_Quit (void) {
00340 CL_Shutdown ();
00341 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
00342 Sys_Exit(0);
00343 }
00344
00345 void Sys_Init(void)
00346 {
00347 Cmd_AddCommand ("in_restart", Sys_In_Restart_f);
00348
00349 #if defined __linux__
00350 #if defined __i386__
00351 Cvar_Set( "arch", "linux i386" );
00352 #elif defined __alpha__
00353 Cvar_Set( "arch", "linux alpha" );
00354 #elif defined __sparc__
00355 Cvar_Set( "arch", "linux sparc" );
00356 #elif defined __FreeBSD__
00357
00358 #if defined __i386__ // FreeBSD
00359 Cvar_Set( "arch", "freebsd i386" );
00360 #elif defined __alpha__
00361 Cvar_Set( "arch", "freebsd alpha" );
00362 #else
00363 Cvar_Set( "arch", "freebsd unknown" );
00364 #endif // FreeBSD
00365
00366 #else
00367 Cvar_Set( "arch", "linux unknown" );
00368 #endif
00369 #elif defined __sun__
00370 #if defined __i386__
00371 Cvar_Set( "arch", "solaris x86" );
00372 #elif defined __sparc__
00373 Cvar_Set( "arch", "solaris sparc" );
00374 #else
00375 Cvar_Set( "arch", "solaris unknown" );
00376 #endif
00377 #elif defined __sgi__
00378 #if defined __mips__
00379 Cvar_Set( "arch", "sgi mips" );
00380 #else
00381 Cvar_Set( "arch", "sgi unknown" );
00382 #endif
00383 #else
00384 Cvar_Set( "arch", "unknown" );
00385 #endif
00386
00387 Cvar_Set( "username", Sys_GetCurrentUser() );
00388
00389 IN_Init();
00390
00391 }
00392
00393 void Sys_Error( const char *error, ...)
00394 {
00395 va_list argptr;
00396 char string[1024];
00397
00398
00399
00400 fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
00401
00402
00403 if (ttycon_on)
00404 {
00405 tty_Hide();
00406 }
00407
00408 CL_Shutdown ();
00409
00410 va_start (argptr,error);
00411 vsprintf (string,error,argptr);
00412 va_end (argptr);
00413 fprintf(stderr, "Sys_Error: %s\n", string);
00414
00415 Sys_Exit( 1 );
00416 }
00417
00418 void Sys_Warn (char *warning, ...)
00419 {
00420 va_list argptr;
00421 char string[1024];
00422
00423 va_start (argptr,warning);
00424 vsprintf (string,warning,argptr);
00425 va_end (argptr);
00426
00427 if (ttycon_on)
00428 {
00429 tty_Hide();
00430 }
00431
00432 fprintf(stderr, "Warning: %s", string);
00433
00434 if (ttycon_on)
00435 {
00436 tty_Show();
00437 }
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 int Sys_FileTime (char *path)
00448 {
00449 struct stat buf;
00450
00451 if (stat (path,&buf) == -1)
00452 return -1;
00453
00454 return buf.st_mtime;
00455 }
00456
00457 void floating_point_exception_handler(int whatever)
00458 {
00459 signal(SIGFPE, floating_point_exception_handler);
00460 }
00461
00462
00463 void Sys_ConsoleInputInit()
00464 {
00465 struct termios tc;
00466
00467
00468
00469
00470
00471 signal(SIGTTIN, SIG_IGN);
00472 signal(SIGTTOU, SIG_IGN);
00473
00474
00475 ttycon = Cvar_Get("ttycon", "1", 0);
00476 if (ttycon && ttycon->value)
00477 {
00478 if (isatty(STDIN_FILENO)!=1)
00479 {
00480 Com_Printf("stdin is not a tty, tty console mode failed\n");
00481 Cvar_Set("ttycon", "0");
00482 ttycon_on = qfalse;
00483 return;
00484 }
00485 Com_Printf("Started tty console (use +set ttycon 0 to disable)\n");
00486 Field_Clear(&tty_con);
00487 tcgetattr (0, &tty_tc);
00488 tty_erase = tty_tc.c_cc[VERASE];
00489 tty_eof = tty_tc.c_cc[VEOF];
00490 tc = tty_tc;
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 tc.c_lflag &= ~(ECHO | ICANON);
00501
00502
00503
00504
00505 tc.c_iflag &= ~(ISTRIP | INPCK);
00506 tc.c_cc[VMIN] = 1;
00507 tc.c_cc[VTIME] = 0;
00508 tcsetattr (0, TCSADRAIN, &tc);
00509 ttycon_on = qtrue;
00510 } else
00511 ttycon_on = qfalse;
00512 }
00513
00514 char *Sys_ConsoleInput(void)
00515 {
00516
00517 static char text[256];
00518 int i;
00519 int avail;
00520 char key;
00521 field_t *history;
00522
00523 if (ttycon && ttycon->value)
00524 {
00525 avail = read(0, &key, 1);
00526 if (avail != -1)
00527 {
00528
00529
00530
00531 if ((key == tty_erase) || (key == 127) || (key == 8))
00532 {
00533 if (tty_con.cursor > 0)
00534 {
00535 tty_con.cursor--;
00536 tty_con.buffer[tty_con.cursor] = '\0';
00537 tty_Back();
00538 }
00539 return NULL;
00540 }
00541
00542 if ((key) && (key) < ' ')
00543 {
00544 if (key == '\n')
00545 {
00546
00547 Hist_Add(&tty_con);
00548 strcpy(text, tty_con.buffer);
00549 Field_Clear(&tty_con);
00550 key = '\n';
00551 write(1, &key, 1);
00552 return text;
00553 }
00554 if (key == '\t')
00555 {
00556 tty_Hide();
00557 Field_CompleteCommand( &tty_con );
00558
00559
00560
00561 tty_con.cursor = strlen(tty_con.buffer);
00562 if (tty_con.cursor>0)
00563 {
00564 if (tty_con.buffer[0] == '\\')
00565 {
00566 for (i=0; i<=tty_con.cursor; i++)
00567 {
00568 tty_con.buffer[i] = tty_con.buffer[i+1];
00569 }
00570 tty_con.cursor--;
00571 }
00572 }
00573 tty_Show();
00574 return NULL;
00575 }
00576 avail = read(0, &key, 1);
00577 if (avail != -1)
00578 {
00579
00580 if (key == '[' || key == 'O')
00581 {
00582 avail = read(0, &key, 1);
00583 if (avail != -1)
00584 {
00585 switch (key)
00586 {
00587 case 'A':
00588 history = Hist_Prev();
00589 if (history)
00590 {
00591 tty_Hide();
00592 tty_con = *history;
00593 tty_Show();
00594 }
00595 tty_FlushIn();
00596 return NULL;
00597 break;
00598 case 'B':
00599 history = Hist_Next();
00600 tty_Hide();
00601 if (history)
00602 {
00603 tty_con = *history;
00604 } else
00605 {
00606 Field_Clear(&tty_con);
00607 }
00608 tty_Show();
00609 tty_FlushIn();
00610 return NULL;
00611 break;
00612 case 'C':
00613 return NULL;
00614 case 'D':
00615 return NULL;
00616 }
00617 }
00618 }
00619 }
00620 Com_DPrintf("droping ISCTL sequence: %d, tty_erase: %d\n", key, tty_erase);
00621 tty_FlushIn();
00622 return NULL;
00623 }
00624
00625 tty_con.buffer[tty_con.cursor] = key;
00626 tty_con.cursor++;
00627
00628 write(1, &key, 1);
00629 }
00630 return NULL;
00631 } else
00632 {
00633 int len;
00634 fd_set fdset;
00635 struct timeval timeout;
00636
00637 if (!com_dedicated || !com_dedicated->value)
00638 return NULL;
00639
00640 if (!stdin_active)
00641 return NULL;
00642
00643 FD_ZERO(&fdset);
00644 FD_SET(0, &fdset);
00645 timeout.tv_sec = 0;
00646 timeout.tv_usec = 0;
00647 if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
00648 {
00649 return NULL;
00650 }
00651
00652 len = read (0, text, sizeof(text));
00653 if (len == 0)
00654 {
00655 stdin_active = qfalse;
00656 return NULL;
00657 }
00658
00659 if (len < 1)
00660 return NULL;
00661 text[len-1] = 0;
00662
00663 return text;
00664 }
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 void Sys_UnloadDll( void *dllHandle ) {
00676
00677 const char* err;
00678 if ( !dllHandle )
00679 {
00680 Com_Printf("Sys_UnloadDll(NULL)\n");
00681 return;
00682 }
00683 dlclose( dllHandle );
00684 err = dlerror();
00685 if ( err != NULL )
00686 Com_Printf ( "Sys_UnloadGame failed on dlclose: \"%s\"!\n", err );
00687 }
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 extern char *FS_BuildOSPath( const char *base, const char *game, const char *qpath );
00703
00704 void *Sys_LoadDll( const char *name, char *fqpath ,
00705 int (**entryPoint)(int, ...),
00706 int (*systemcalls)(int, ...) )
00707 {
00708 void *libHandle;
00709 void (*dllEntry)( int (*syscallptr)(int, ...) );
00710 char curpath[MAX_OSPATH];
00711 char fname[MAX_OSPATH];
00712 char *basepath;
00713 char *homepath;
00714 char *pwdpath;
00715 char *gamedir;
00716 char *fn;
00717 const char* err = NULL;
00718
00719 *fqpath = 0;
00720
00721
00722 assert( name );
00723
00724 getcwd(curpath, sizeof(curpath));
00725 #if defined __i386__
00726 snprintf (fname, sizeof(fname), "%si386.so", name);
00727 #elif defined __powerpc__ //rcg010207 - PPC support.
00728 snprintf (fname, sizeof(fname), "%sppc.so", name);
00729 #elif defined __axp__
00730 snprintf (fname, sizeof(fname), "%saxp.so", name);
00731 #elif defined __mips__
00732 snprintf (fname, sizeof(fname), "%smips.so", name);
00733 #else
00734 #error Unknown arch
00735 #endif
00736
00737
00738 #define Q_RTLD RTLD_NOW
00739
00740 pwdpath = Sys_Cwd();
00741 basepath = Cvar_VariableString( "fs_basepath" );
00742 homepath = Cvar_VariableString( "fs_homepath" );
00743 gamedir = Cvar_VariableString( "fs_game" );
00744
00745
00746 fn = FS_BuildOSPath( pwdpath, gamedir, fname );
00747 Com_Printf( "Sys_LoadDll(%s)... \n", fn );
00748 libHandle = dlopen( fn, Q_RTLD );
00749
00750 if ( !libHandle )
00751 {
00752 Com_Printf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() );
00753
00754 fn = FS_BuildOSPath( homepath, gamedir, fname );
00755 Com_Printf( "Sys_LoadDll(%s)... \n", fn );
00756 libHandle = dlopen( fn, Q_RTLD );
00757
00758 if ( !libHandle )
00759 {
00760 Com_Printf( "Sys_LoadDll(%s) failed:\n\"%s\"\n", fn, dlerror() );
00761
00762 fn = FS_BuildOSPath( basepath, gamedir, fname );
00763 Com_Printf( "Sys_LoadDll(%s)... \n", fn );
00764 libHandle = dlopen( fn, Q_RTLD );
00765
00766 if ( !libHandle )
00767 {
00768 #ifndef NDEBUG // bk001206 - in debug abort on failure
00769 Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlopen() completely!\n", name );
00770 #else
00771 Com_Printf ( "Sys_LoadDll(%s) failed dlopen() completely!\n", name );
00772 #endif
00773 return NULL;
00774 } else
00775 Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", fn );
00776 } else
00777 Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", fn );
00778 } else
00779 Com_Printf ( "Sys_LoadDll(%s): succeeded ...\n", fn );
00780
00781 dllEntry = dlsym( libHandle, "dllEntry" );
00782 *entryPoint = dlsym( libHandle, "vmMain" );
00783 if ( !*entryPoint || !dllEntry )
00784 {
00785 err = dlerror();
00786 #ifndef NDEBUG // bk001206 - in debug abort on failure
00787 Com_Error ( ERR_FATAL, "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
00788 #else
00789 Com_Printf ( "Sys_LoadDll(%s) failed dlsym(vmMain):\n\"%s\" !\n", name, err );
00790 #endif
00791 dlclose( libHandle );
00792 err = dlerror();
00793 if ( err != NULL )
00794 Com_Printf ( "Sys_LoadDll(%s) failed dlcose:\n\"%s\"\n", name, err );
00795 return NULL;
00796 }
00797 Com_Printf ( "Sys_LoadDll(%s) found **vmMain** at %p \n", name, *entryPoint );
00798 dllEntry( systemcalls );
00799 Com_Printf ( "Sys_LoadDll(%s) succeeded!\n", name );
00800 if ( libHandle ) Q_strncpyz ( fqpath , fn , MAX_QPATH ) ;
00801 return libHandle;
00802 }
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812 #if 1
00813
00814 void Sys_InitStreamThread( void ) {
00815 }
00816
00817 void Sys_ShutdownStreamThread( void ) {
00818 }
00819
00820 void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) {
00821 }
00822
00823 void Sys_EndStreamedFile( fileHandle_t f ) {
00824 }
00825
00826 int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) {
00827 return FS_Read( buffer, size * count, f );
00828 }
00829
00830 void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) {
00831 FS_Seek( f, offset, origin );
00832 }
00833
00834 #else
00835
00836 typedef struct
00837 {
00838 fileHandle_t file;
00839 byte *buffer;
00840 qboolean eof;
00841 int bufferSize;
00842 int streamPosition;
00843 int threadPosition;
00844 } streamState_t;
00845
00846 streamState_t stream;
00847
00848
00849
00850
00851
00852
00853
00854
00855 void Sys_StreamThread( void )
00856 {
00857 int buffer;
00858 int count;
00859 int readCount;
00860 int bufferPoint;
00861 int r;
00862
00863
00864 if ( !stream.eof )
00865 {
00866 count = stream.bufferSize - (stream.threadPosition - stream.streamPosition);
00867 if ( count )
00868 {
00869 bufferPoint = stream.threadPosition % stream.bufferSize;
00870 buffer = stream.bufferSize - bufferPoint;
00871 readCount = buffer < count ? buffer : count;
00872 r = FS_Read ( stream.buffer + bufferPoint, readCount, stream.file );
00873 stream.threadPosition += r;
00874
00875 if ( r != readCount )
00876 stream.eof = qtrue;
00877 }
00878 }
00879 }
00880
00881
00882
00883
00884
00885
00886
00887 void Sys_InitStreamThread( void )
00888 {
00889 }
00890
00891
00892
00893
00894
00895
00896
00897 void Sys_ShutdownStreamThread( void )
00898 {
00899 }
00900
00901
00902
00903
00904
00905
00906
00907
00908 void Sys_BeginStreamedFile( fileHandle_t f, int readAhead )
00909 {
00910 if ( stream.file )
00911 {
00912 Com_Error( ERR_FATAL, "Sys_BeginStreamedFile: unclosed stream");
00913 }
00914
00915 stream.file = f;
00916 stream.buffer = Z_Malloc( readAhead );
00917 stream.bufferSize = readAhead;
00918 stream.streamPosition = 0;
00919 stream.threadPosition = 0;
00920 stream.eof = qfalse;
00921 }
00922
00923
00924
00925
00926
00927
00928
00929 void Sys_EndStreamedFile( fileHandle_t f )
00930 {
00931 if ( f != stream.file )
00932 {
00933 Com_Error( ERR_FATAL, "Sys_EndStreamedFile: wrong file");
00934 }
00935
00936 stream.file = 0;
00937 Z_Free( stream.buffer );
00938 }
00939
00940
00941
00942
00943
00944
00945
00946
00947 int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f )
00948 {
00949 int available;
00950 int remaining;
00951 int sleepCount;
00952 int copy;
00953 int bufferCount;
00954 int bufferPoint;
00955 byte *dest;
00956
00957 dest = (byte *)buffer;
00958 remaining = size * count;
00959
00960 if ( remaining <= 0 )
00961 {
00962 Com_Error( ERR_FATAL, "Streamed read with non-positive size" );
00963 }
00964
00965 sleepCount = 0;
00966 while ( remaining > 0 )
00967 {
00968 available = stream.threadPosition - stream.streamPosition;
00969 if ( !available )
00970 {
00971 if (stream.eof)
00972 break;
00973 Sys_StreamThread();
00974 continue;
00975 }
00976
00977 bufferPoint = stream.streamPosition % stream.bufferSize;
00978 bufferCount = stream.bufferSize - bufferPoint;
00979
00980 copy = available < bufferCount ? available : bufferCount;
00981 if ( copy > remaining )
00982 {
00983 copy = remaining;
00984 }
00985 memcpy( dest, stream.buffer + bufferPoint, copy );
00986 stream.streamPosition += copy;
00987 dest += copy;
00988 remaining -= copy;
00989 }
00990
00991 return(count * size - remaining) / size;
00992 }
00993
00994
00995
00996
00997
00998
00999
01000 void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) {
01001
01002 FS_Seek( f, offset, origin );
01003 stream.streamPosition = 0;
01004 stream.threadPosition = 0;
01005 stream.eof = qfalse;
01006 }
01007
01008 #endif
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019 #define MAX_QUED_EVENTS 256
01020 #define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 )
01021
01022 sysEvent_t eventQue[MAX_QUED_EVENTS];
01023
01024 int eventHead = 0;
01025 int eventTail = 0;
01026 byte sys_packetReceived[MAX_MSGLEN];
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037 void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) {
01038 sysEvent_t *ev;
01039
01040 ev = &eventQue[ eventHead & MASK_QUED_EVENTS ];
01041
01042
01043 if ( eventHead - eventTail >= MAX_QUED_EVENTS )
01044 {
01045 Com_Printf("Sys_QueEvent: overflow\n");
01046
01047 if ( ev->evPtr )
01048 {
01049 Z_Free( ev->evPtr );
01050 }
01051 eventTail++;
01052 }
01053
01054 eventHead++;
01055
01056 if ( time == 0 )
01057 {
01058 time = Sys_Milliseconds();
01059 }
01060
01061 ev->evTime = time;
01062 ev->evType = type;
01063 ev->evValue = value;
01064 ev->evValue2 = value2;
01065 ev->evPtrLength = ptrLength;
01066 ev->evPtr = ptr;
01067 }
01068
01069
01070
01071
01072
01073
01074
01075 sysEvent_t Sys_GetEvent( void ) {
01076 sysEvent_t ev;
01077 char *s;
01078 msg_t netmsg;
01079 netadr_t adr;
01080
01081
01082 if ( eventHead > eventTail )
01083 {
01084 eventTail++;
01085 return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
01086 }
01087
01088
01089
01090 Sys_SendKeyEvents ();
01091
01092
01093 s = Sys_ConsoleInput();
01094 if ( s )
01095 {
01096 char *b;
01097 int len;
01098
01099 len = strlen( s ) + 1;
01100 b = Z_Malloc( len );
01101 strcpy( b, s );
01102 Sys_QueEvent( 0, SE_CONSOLE, 0, 0, len, b );
01103 }
01104
01105
01106 IN_Frame();
01107
01108
01109 MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
01110 if ( Sys_GetPacket ( &adr, &netmsg ) )
01111 {
01112 netadr_t *buf;
01113 int len;
01114
01115
01116 len = sizeof( netadr_t ) + netmsg.cursize;
01117 buf = Z_Malloc( len );
01118 *buf = adr;
01119 memcpy( buf+1, netmsg.data, netmsg.cursize );
01120 Sys_QueEvent( 0, SE_PACKET, 0, 0, len, buf );
01121 }
01122
01123
01124 if ( eventHead > eventTail )
01125 {
01126 eventTail++;
01127 return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
01128 }
01129
01130
01131
01132 memset( &ev, 0, sizeof( ev ) );
01133 ev.evTime = Sys_Milliseconds();
01134
01135 return ev;
01136 }
01137
01138
01139
01140 qboolean Sys_CheckCD( void ) {
01141 return qtrue;
01142 }
01143
01144 void Sys_AppActivate (void)
01145 {
01146 }
01147
01148 char *Sys_GetClipboardData(void)
01149 {
01150 return NULL;
01151 }
01152
01153 void Sys_Print( const char *msg )
01154 {
01155 if (ttycon_on)
01156 {
01157 tty_Hide();
01158 }
01159 fputs(msg, stderr);
01160 if (ttycon_on)
01161 {
01162 tty_Show();
01163 }
01164 }
01165
01166
01167 void Sys_ConfigureFPU() {
01168 #ifdef __linux__
01169 #ifdef __i386
01170 #ifndef NDEBUG
01171
01172
01173 static int fpu_word = _FPU_DEFAULT & ~(_FPU_MASK_ZM | _FPU_MASK_IM);
01174 int current = 0;
01175 _FPU_GETCW(current);
01176 if ( current!=fpu_word)
01177 {
01178 #if 0
01179 Com_Printf("FPU Control 0x%x (was 0x%x)\n", fpu_word, current );
01180 _FPU_SETCW( fpu_word );
01181 _FPU_GETCW( current );
01182 assert(fpu_word==current);
01183 #endif
01184 }
01185 #else // NDEBUG
01186 static int fpu_word = _FPU_DEFAULT;
01187 _FPU_SETCW( fpu_word );
01188 #endif // NDEBUG
01189 #endif // __i386
01190 #endif // __linux
01191 }
01192
01193 void Sys_PrintBinVersion( const char* name ) {
01194 char* date = __DATE__;
01195 char* time = __TIME__;
01196 char* sep = "==============================================================";
01197 fprintf( stdout, "\n\n%s\n", sep );
01198 #ifdef DEDICATED
01199 fprintf( stdout, "Linux Quake3 Dedicated Server [%s %s]\n", date, time );
01200 #else
01201 fprintf( stdout, "Linux Quake3 Full Executable [%s %s]\n", date, time );
01202 #endif
01203 fprintf( stdout, " local install: %s\n", name );
01204 fprintf( stdout, "%s\n\n", sep );
01205 }
01206
01207 void Sys_ParseArgs( int argc, char* argv[] ) {
01208
01209 if ( argc==2 )
01210 {
01211 if ( (!strcmp( argv[1], "--version" ))
01212 || ( !strcmp( argv[1], "-v" )) )
01213 {
01214 Sys_PrintBinVersion( argv[0] );
01215 Sys_Exit(0);
01216 }
01217 }
01218 }
01219
01220 #include "../client/client.h"
01221 extern clientStatic_t cls;
01222
01223 int main ( int argc, char* argv[] )
01224 {
01225
01226 int len, i;
01227 char *cmdline;
01228 void Sys_SetDefaultCDPath(const char *path);
01229
01230
01231 saved_euid = geteuid();
01232 seteuid(getuid());
01233
01234 Sys_ParseArgs( argc, argv );
01235
01236 Sys_SetDefaultCDPath(argv[0]);
01237
01238
01239 for (len = 1, i = 1; i < argc; i++)
01240 len += strlen(argv[i]) + 1;
01241 cmdline = malloc(len);
01242 *cmdline = 0;
01243 for (i = 1; i < argc; i++)
01244 {
01245 if (i > 1)
01246 strcat(cmdline, " ");
01247 strcat(cmdline, argv[i]);
01248 }
01249
01250
01251 memset( &eventQue[0], 0, MAX_QUED_EVENTS*sizeof(sysEvent_t) );
01252 memset( &sys_packetReceived[0], 0, MAX_MSGLEN*sizeof(byte) );
01253
01254 Com_Init(cmdline);
01255 NET_Init();
01256
01257 Sys_ConsoleInputInit();
01258
01259 fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
01260
01261 #ifdef DEDICATED
01262
01263 InitSig();
01264 #endif
01265
01266 while (1)
01267 {
01268 #ifdef __linux__
01269 Sys_ConfigureFPU();
01270 #endif
01271 Com_Frame ();
01272 }
01273 }