00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "../client/client.h"
00025 #include "../qcommon/qcommon.h"
00026 #include "win_local.h"
00027 #include "resource.h"
00028 #include <errno.h>
00029 #include <float.h>
00030 #include <fcntl.h>
00031 #include <stdio.h>
00032 #include <direct.h>
00033 #include <io.h>
00034 #include <conio.h>
00035
00036 #define CD_BASEDIR "quake3"
00037 #define CD_EXE "quake3.exe"
00038 #define CD_BASEDIR_LINUX "bin\\x86\\glibc-2.1"
00039 #define CD_EXE_LINUX "quake3"
00040 #define MEM_THRESHOLD 96*1024*1024
00041
00042 static char sys_cmdline[MAX_STRING_CHARS];
00043
00044
00045
00046
00047 #define ALT_SPANK
00048 #ifdef ALT_SPANK
00049 #include <stdio.h>
00050 #include <sys\stat.h>
00051
00052 int fh = 0;
00053
00054 void Spk_Open(char *name)
00055 {
00056 fh = open( name, O_TRUNC | O_CREAT | O_WRONLY, S_IREAD | S_IWRITE );
00057 };
00058
00059 void Spk_Close()
00060 {
00061 if (!fh)
00062 return;
00063
00064 close( fh );
00065 fh = 0;
00066 }
00067
00068 void Spk_Printf (const char *text, ...)
00069 {
00070 va_list argptr;
00071 char buf[32768];
00072
00073 if (!fh)
00074 return;
00075
00076 va_start (argptr,text);
00077 vsprintf (buf, text, argptr);
00078 write(fh, buf, strlen(buf));
00079 _commit(fh);
00080 va_end (argptr);
00081
00082 };
00083 #endif
00084
00085
00086
00087
00088
00089
00090
00091 qboolean Sys_LowPhysicalMemory() {
00092 MEMORYSTATUS stat;
00093 GlobalMemoryStatus (&stat);
00094 return (stat.dwTotalPhys <= MEM_THRESHOLD) ? qtrue : qfalse;
00095 }
00096
00097
00098
00099
00100
00101
00102 void Sys_BeginProfiling( void ) {
00103
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113 void QDECL Sys_Error( const char *error, ... ) {
00114 va_list argptr;
00115 char text[4096];
00116 MSG msg;
00117
00118 va_start (argptr, error);
00119 vsprintf (text, error, argptr);
00120 va_end (argptr);
00121
00122 Conbuf_AppendText( text );
00123 Conbuf_AppendText( "\n" );
00124
00125 Sys_SetErrorText( text );
00126 Sys_ShowConsole( 1, qtrue );
00127
00128 timeEndPeriod( 1 );
00129
00130 IN_Shutdown();
00131
00132
00133 while ( 1 ) {
00134 if (!GetMessage (&msg, NULL, 0, 0))
00135 Com_Quit_f ();
00136 TranslateMessage (&msg);
00137 DispatchMessage (&msg);
00138 }
00139
00140 Sys_DestroyConsole();
00141
00142 exit (1);
00143 }
00144
00145
00146
00147
00148
00149
00150 void Sys_Quit( void ) {
00151 timeEndPeriod( 1 );
00152 IN_Shutdown();
00153 Sys_DestroyConsole();
00154
00155 exit (0);
00156 }
00157
00158
00159
00160
00161
00162
00163 void Sys_Print( const char *msg ) {
00164 Conbuf_AppendText( msg );
00165 }
00166
00167
00168
00169
00170
00171
00172
00173 void Sys_Mkdir( const char *path ) {
00174 _mkdir (path);
00175 }
00176
00177
00178
00179
00180
00181
00182 char *Sys_Cwd( void ) {
00183 static char cwd[MAX_OSPATH];
00184
00185 _getcwd( cwd, sizeof( cwd ) - 1 );
00186 cwd[MAX_OSPATH-1] = 0;
00187
00188 return cwd;
00189 }
00190
00191
00192
00193
00194
00195
00196 char *Sys_DefaultCDPath( void ) {
00197 return "";
00198 }
00199
00200
00201
00202
00203
00204
00205 char *Sys_DefaultBasePath( void ) {
00206 return Sys_Cwd();
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 #define MAX_FOUND_FILES 0x1000
00218
00219 void Sys_ListFilteredFiles( const char *basedir, char *subdirs, char *filter, char **list, int *numfiles ) {
00220 char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
00221 char filename[MAX_OSPATH];
00222 int findhandle;
00223 struct _finddata_t findinfo;
00224
00225 if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
00226 return;
00227 }
00228
00229 if (strlen(subdirs)) {
00230 Com_sprintf( search, sizeof(search), "%s\\%s\\*", basedir, subdirs );
00231 }
00232 else {
00233 Com_sprintf( search, sizeof(search), "%s\\*", basedir );
00234 }
00235
00236 findhandle = _findfirst (search, &findinfo);
00237 if (findhandle == -1) {
00238 return;
00239 }
00240
00241 do {
00242 if (findinfo.attrib & _A_SUBDIR) {
00243 if (Q_stricmp(findinfo.name, ".") && Q_stricmp(findinfo.name, "..")) {
00244 if (strlen(subdirs)) {
00245 Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s\\%s", subdirs, findinfo.name);
00246 }
00247 else {
00248 Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s", findinfo.name);
00249 }
00250 Sys_ListFilteredFiles( basedir, newsubdirs, filter, list, numfiles );
00251 }
00252 }
00253 if ( *numfiles >= MAX_FOUND_FILES - 1 ) {
00254 break;
00255 }
00256 Com_sprintf( filename, sizeof(filename), "%s\\%s", subdirs, findinfo.name );
00257 if (!Com_FilterPath( filter, filename, qfalse ))
00258 continue;
00259 list[ *numfiles ] = CopyString( filename );
00260 (*numfiles)++;
00261 } while ( _findnext (findhandle, &findinfo) != -1 );
00262
00263 _findclose (findhandle);
00264 }
00265
00266 static qboolean strgtr(const char *s0, const char *s1) {
00267 int l0, l1, i;
00268
00269 l0 = strlen(s0);
00270 l1 = strlen(s1);
00271
00272 if (l1<l0) {
00273 l0 = l1;
00274 }
00275
00276 for(i=0;i<l0;i++) {
00277 if (s1[i] > s0[i]) {
00278 return qtrue;
00279 }
00280 if (s1[i] < s0[i]) {
00281 return qfalse;
00282 }
00283 }
00284 return qfalse;
00285 }
00286
00287 char **Sys_ListFiles( const char *directory, const char *extension, char *filter, int *numfiles, qboolean wantsubs ) {
00288 char search[MAX_OSPATH];
00289 int nfiles;
00290 char **listCopy;
00291 char *list[MAX_FOUND_FILES];
00292 struct _finddata_t findinfo;
00293 int findhandle;
00294 int flag;
00295 int i;
00296
00297 if (filter) {
00298
00299 nfiles = 0;
00300 Sys_ListFilteredFiles( directory, "", filter, list, &nfiles );
00301
00302 list[ nfiles ] = 0;
00303 *numfiles = nfiles;
00304
00305 if (!nfiles)
00306 return NULL;
00307
00308 listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) );
00309 for ( i = 0 ; i < nfiles ; i++ ) {
00310 listCopy[i] = list[i];
00311 }
00312 listCopy[i] = NULL;
00313
00314 return listCopy;
00315 }
00316
00317 if ( !extension) {
00318 extension = "";
00319 }
00320
00321
00322 if ( extension[0] == '/' && extension[1] == 0 ) {
00323 extension = "";
00324 flag = 0;
00325 } else {
00326 flag = _A_SUBDIR;
00327 }
00328
00329 Com_sprintf( search, sizeof(search), "%s\\*%s", directory, extension );
00330
00331
00332 nfiles = 0;
00333
00334 findhandle = _findfirst (search, &findinfo);
00335 if (findhandle == -1) {
00336 *numfiles = 0;
00337 return NULL;
00338 }
00339
00340 do {
00341 if ( (!wantsubs && flag ^ ( findinfo.attrib & _A_SUBDIR )) || (wantsubs && findinfo.attrib & _A_SUBDIR) ) {
00342 if ( nfiles == MAX_FOUND_FILES - 1 ) {
00343 break;
00344 }
00345 list[ nfiles ] = CopyString( findinfo.name );
00346 nfiles++;
00347 }
00348 } while ( _findnext (findhandle, &findinfo) != -1 );
00349
00350 list[ nfiles ] = 0;
00351
00352 _findclose (findhandle);
00353
00354
00355 *numfiles = nfiles;
00356
00357 if ( !nfiles ) {
00358 return NULL;
00359 }
00360
00361 listCopy = Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) );
00362 for ( i = 0 ; i < nfiles ; i++ ) {
00363 listCopy[i] = list[i];
00364 }
00365 listCopy[i] = NULL;
00366
00367 do {
00368 flag = 0;
00369 for(i=1; i<nfiles; i++) {
00370 if (strgtr(listCopy[i-1], listCopy[i])) {
00371 char *temp = listCopy[i];
00372 listCopy[i] = listCopy[i-1];
00373 listCopy[i-1] = temp;
00374 flag = 1;
00375 }
00376 }
00377 } while(flag);
00378
00379 return listCopy;
00380 }
00381
00382 void Sys_FreeFileList( char **list ) {
00383 int i;
00384
00385 if ( !list ) {
00386 return;
00387 }
00388
00389 for ( i = 0 ; list[i] ; i++ ) {
00390 Z_Free( list[i] );
00391 }
00392
00393 Z_Free( list );
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 qboolean Sys_ScanForCD( void ) {
00408 static char cddir[MAX_OSPATH];
00409 char drive[4];
00410 FILE *f;
00411 char test[MAX_OSPATH];
00412 #if 0
00413
00414 if ( strstr( sys_cmdline, "cdpath" ) ) {
00415 return;
00416 }
00417 #endif
00418
00419 drive[0] = 'c';
00420 drive[1] = ':';
00421 drive[2] = '\\';
00422 drive[3] = 0;
00423
00424
00425 for ( drive[0] = 'c' ; drive[0] <= 'z' ; drive[0]++ ) {
00426 if ( GetDriveType (drive) != DRIVE_CDROM ) {
00427 continue;
00428 }
00429
00430 sprintf (cddir, "%s%s", drive, CD_BASEDIR);
00431 sprintf (test, "%s\\%s", cddir, CD_EXE);
00432 f = fopen( test, "r" );
00433 if ( f ) {
00434 fclose (f);
00435 return qtrue;
00436 } else {
00437 sprintf(cddir, "%s%s", drive, CD_BASEDIR_LINUX);
00438 sprintf(test, "%s\\%s", cddir, CD_EXE_LINUX);
00439 f = fopen( test, "r" );
00440 if ( f ) {
00441 fclose (f);
00442 return qtrue;
00443 }
00444 }
00445 }
00446
00447 return qfalse;
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457 qboolean Sys_CheckCD( void ) {
00458
00459 return qtrue;
00460
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470 char *Sys_GetClipboardData( void ) {
00471 char *data = NULL;
00472 char *cliptext;
00473
00474 if ( OpenClipboard( NULL ) != 0 ) {
00475 HANDLE hClipboardData;
00476
00477 if ( ( hClipboardData = GetClipboardData( CF_TEXT ) ) != 0 ) {
00478 if ( ( cliptext = GlobalLock( hClipboardData ) ) != 0 ) {
00479 data = Z_Malloc( GlobalSize( hClipboardData ) + 1 );
00480 Q_strncpyz( data, cliptext, GlobalSize( hClipboardData ) );
00481 GlobalUnlock( hClipboardData );
00482
00483 strtok( data, "\n\r\b" );
00484 }
00485 }
00486 CloseClipboard();
00487 }
00488 return data;
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 void Sys_UnloadDll( void *dllHandle ) {
00507 if ( !dllHandle ) {
00508 return;
00509 }
00510 if ( !FreeLibrary( dllHandle ) ) {
00511 Com_Error (ERR_FATAL, "Sys_UnloadDll FreeLibrary failed");
00512 }
00513 }
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 extern char *FS_BuildOSPath( const char *base, const char *game, const char *qpath );
00525
00526
00527
00528
00529 void * QDECL Sys_LoadDll( const char *name, char *fqpath , int (QDECL **entryPoint)(int, ...),
00530 int (QDECL *systemcalls)(int, ...) ) {
00531 static int lastWarning = 0;
00532 HINSTANCE libHandle;
00533 void (QDECL *dllEntry)( int (QDECL *syscallptr)(int, ...) );
00534 char *basepath;
00535 char *cdpath;
00536 char *gamedir;
00537 char *fn;
00538 #ifdef NDEBUG
00539 int timestamp;
00540 int ret;
00541 #endif
00542 char filename[MAX_QPATH];
00543
00544 *fqpath = 0 ;
00545
00546 Com_sprintf( filename, sizeof( filename ), "%sx86.dll", name );
00547
00548 #ifdef NDEBUG
00549 timestamp = Sys_Milliseconds();
00550 if( ((timestamp - lastWarning) > (5 * 60000)) && !Cvar_VariableIntegerValue( "dedicated" )
00551 && !Cvar_VariableIntegerValue( "com_blindlyLoadDLLs" ) ) {
00552 if (FS_FileExists(filename)) {
00553 lastWarning = timestamp;
00554 ret = MessageBoxEx( NULL, "You are about to load a .DLL executable that\n"
00555 "has not been verified for use with Quake III Arena.\n"
00556 "This type of file can compromise the security of\n"
00557 "your computer.\n\n"
00558 "Select 'OK' if you choose to load it anyway.",
00559 "Security Warning", MB_OKCANCEL | MB_ICONEXCLAMATION | MB_DEFBUTTON2 | MB_TOPMOST | MB_SETFOREGROUND,
00560 MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
00561 if( ret != IDOK ) {
00562 return NULL;
00563 }
00564 }
00565 }
00566 #endif
00567
00568 #ifndef NDEBUG
00569 libHandle = LoadLibrary( filename );
00570 if (libHandle)
00571 Com_Printf("LoadLibrary '%s' ok\n", filename);
00572 else
00573 Com_Printf("LoadLibrary '%s' failed\n", filename);
00574 if ( !libHandle ) {
00575 #endif
00576 basepath = Cvar_VariableString( "fs_basepath" );
00577 cdpath = Cvar_VariableString( "fs_cdpath" );
00578 gamedir = Cvar_VariableString( "fs_game" );
00579
00580 fn = FS_BuildOSPath( basepath, gamedir, filename );
00581 libHandle = LoadLibrary( fn );
00582 #ifndef NDEBUG
00583 if (libHandle)
00584 Com_Printf("LoadLibrary '%s' ok\n", fn);
00585 else
00586 Com_Printf("LoadLibrary '%s' failed\n", fn);
00587 #endif
00588
00589 if ( !libHandle ) {
00590 if( cdpath[0] ) {
00591 fn = FS_BuildOSPath( cdpath, gamedir, filename );
00592 libHandle = LoadLibrary( fn );
00593 #ifndef NDEBUG
00594 if (libHandle)
00595 Com_Printf("LoadLibrary '%s' ok\n", fn);
00596 else
00597 Com_Printf("LoadLibrary '%s' failed\n", fn);
00598 #endif
00599 }
00600
00601 if ( !libHandle ) {
00602 return NULL;
00603 }
00604 }
00605 #ifndef NDEBUG
00606 }
00607 #endif
00608
00609 dllEntry = ( void (QDECL *)( int (QDECL *)( int, ... ) ) )GetProcAddress( libHandle, "dllEntry" );
00610 *entryPoint = (int (QDECL *)(int,...))GetProcAddress( libHandle, "vmMain" );
00611 if ( !*entryPoint || !dllEntry ) {
00612 FreeLibrary( libHandle );
00613 return NULL;
00614 }
00615 dllEntry( systemcalls );
00616
00617 if ( libHandle ) Q_strncpyz ( fqpath , filename , MAX_QPATH ) ;
00618 return libHandle;
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630 #if 1
00631
00632 void Sys_InitStreamThread( void ) {
00633 }
00634
00635 void Sys_ShutdownStreamThread( void ) {
00636 }
00637
00638 void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) {
00639 }
00640
00641 void Sys_EndStreamedFile( fileHandle_t f ) {
00642 }
00643
00644 int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) {
00645 return FS_Read( buffer, size * count, f );
00646 }
00647
00648 void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) {
00649 FS_Seek( f, offset, origin );
00650 }
00651
00652
00653 #else
00654
00655 typedef struct {
00656 fileHandle_t file;
00657 byte *buffer;
00658 qboolean eof;
00659 qboolean active;
00660 int bufferSize;
00661 int streamPosition;
00662 int threadPosition;
00663 } streamsIO_t;
00664
00665 typedef struct {
00666 HANDLE threadHandle;
00667 int threadId;
00668 CRITICAL_SECTION crit;
00669 streamsIO_t sIO[MAX_FILE_HANDLES];
00670 } streamState_t;
00671
00672 streamState_t stream;
00673
00674
00675
00676
00677
00678
00679
00680
00681 void Sys_StreamThread( void ) {
00682 int buffer;
00683 int count;
00684 int readCount;
00685 int bufferPoint;
00686 int r, i;
00687
00688 while (1) {
00689 Sleep( 10 );
00690
00691
00692 for (i=1;i<MAX_FILE_HANDLES;i++) {
00693
00694 if ( stream.sIO[i].active && !stream.sIO[i].eof ) {
00695 count = stream.sIO[i].bufferSize - (stream.sIO[i].threadPosition - stream.sIO[i].streamPosition);
00696 if ( !count ) {
00697 continue;
00698 }
00699
00700 bufferPoint = stream.sIO[i].threadPosition % stream.sIO[i].bufferSize;
00701 buffer = stream.sIO[i].bufferSize - bufferPoint;
00702 readCount = buffer < count ? buffer : count;
00703
00704 r = FS_Read( stream.sIO[i].buffer + bufferPoint, readCount, stream.sIO[i].file );
00705 stream.sIO[i].threadPosition += r;
00706
00707 if ( r != readCount ) {
00708 stream.sIO[i].eof = qtrue;
00709 }
00710 }
00711 }
00712
00713 }
00714 }
00715
00716
00717
00718
00719
00720
00721
00722 void Sys_InitStreamThread( void ) {
00723 int i;
00724
00725 InitializeCriticalSection ( &stream.crit );
00726
00727
00728
00729
00730
00731
00732 stream.threadHandle = CreateThread(
00733 NULL,
00734 0,
00735 (LPTHREAD_START_ROUTINE)Sys_StreamThread,
00736 0,
00737 0,
00738 &stream.threadId);
00739 for(i=0;i<MAX_FILE_HANDLES;i++) {
00740 stream.sIO[i].active = qfalse;
00741 }
00742 }
00743
00744
00745
00746
00747
00748
00749
00750 void Sys_ShutdownStreamThread( void ) {
00751 }
00752
00753
00754
00755
00756
00757
00758
00759
00760 void Sys_BeginStreamedFile( fileHandle_t f, int readAhead ) {
00761 if ( stream.sIO[f].file ) {
00762 Sys_EndStreamedFile( stream.sIO[f].file );
00763 }
00764
00765 stream.sIO[f].file = f;
00766 stream.sIO[f].buffer = Z_Malloc( readAhead );
00767 stream.sIO[f].bufferSize = readAhead;
00768 stream.sIO[f].streamPosition = 0;
00769 stream.sIO[f].threadPosition = 0;
00770 stream.sIO[f].eof = qfalse;
00771 stream.sIO[f].active = qtrue;
00772
00773
00774
00775 }
00776
00777
00778
00779
00780
00781
00782
00783 void Sys_EndStreamedFile( fileHandle_t f ) {
00784 if ( f != stream.sIO[f].file ) {
00785 Com_Error( ERR_FATAL, "Sys_EndStreamedFile: wrong file");
00786 }
00787
00788 EnterCriticalSection( &stream.crit );
00789
00790 stream.sIO[f].file = 0;
00791 stream.sIO[f].active = qfalse;
00792
00793 Z_Free( stream.sIO[f].buffer );
00794
00795 LeaveCriticalSection( &stream.crit );
00796 }
00797
00798
00799
00800
00801
00802
00803
00804
00805 int Sys_StreamedRead( void *buffer, int size, int count, fileHandle_t f ) {
00806 int available;
00807 int remaining;
00808 int sleepCount;
00809 int copy;
00810 int bufferCount;
00811 int bufferPoint;
00812 byte *dest;
00813
00814 if (stream.sIO[f].active == qfalse) {
00815 Com_Error( ERR_FATAL, "Streamed read with non-streaming file" );
00816 }
00817
00818 dest = (byte *)buffer;
00819 remaining = size * count;
00820
00821 if ( remaining <= 0 ) {
00822 Com_Error( ERR_FATAL, "Streamed read with non-positive size" );
00823 }
00824
00825 sleepCount = 0;
00826 while ( remaining > 0 ) {
00827 available = stream.sIO[f].threadPosition - stream.sIO[f].streamPosition;
00828 if ( !available ) {
00829 if ( stream.sIO[f].eof ) {
00830 break;
00831 }
00832 if ( sleepCount == 1 ) {
00833 Com_DPrintf( "Sys_StreamedRead: waiting\n" );
00834 }
00835 if ( ++sleepCount > 100 ) {
00836 Com_Error( ERR_FATAL, "Sys_StreamedRead: thread has died");
00837 }
00838 Sleep( 10 );
00839 continue;
00840 }
00841
00842 EnterCriticalSection( &stream.crit );
00843
00844 bufferPoint = stream.sIO[f].streamPosition % stream.sIO[f].bufferSize;
00845 bufferCount = stream.sIO[f].bufferSize - bufferPoint;
00846
00847 copy = available < bufferCount ? available : bufferCount;
00848 if ( copy > remaining ) {
00849 copy = remaining;
00850 }
00851 memcpy( dest, stream.sIO[f].buffer + bufferPoint, copy );
00852 stream.sIO[f].streamPosition += copy;
00853 dest += copy;
00854 remaining -= copy;
00855
00856 LeaveCriticalSection( &stream.crit );
00857 }
00858
00859 return (count * size - remaining) / size;
00860 }
00861
00862
00863
00864
00865
00866
00867
00868 void Sys_StreamSeek( fileHandle_t f, int offset, int origin ) {
00869
00870
00871 EnterCriticalSection( &stream.crit );
00872
00873
00874 FS_Seek( f, offset, origin );
00875 stream.sIO[f].streamPosition = 0;
00876 stream.sIO[f].threadPosition = 0;
00877 stream.sIO[f].eof = qfalse;
00878
00879
00880 LeaveCriticalSection( &stream.crit );
00881 }
00882
00883 #endif
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893 #define MAX_QUED_EVENTS 256
00894 #define MASK_QUED_EVENTS ( MAX_QUED_EVENTS - 1 )
00895
00896 sysEvent_t eventQue[MAX_QUED_EVENTS];
00897 int eventHead, eventTail;
00898 byte sys_packetReceived[MAX_MSGLEN];
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 void Sys_QueEvent( int time, sysEventType_t type, int value, int value2, int ptrLength, void *ptr ) {
00910 sysEvent_t *ev;
00911
00912 ev = &eventQue[ eventHead & MASK_QUED_EVENTS ];
00913 if ( eventHead - eventTail >= MAX_QUED_EVENTS ) {
00914 Com_Printf("Sys_QueEvent: overflow\n");
00915
00916 if ( ev->evPtr ) {
00917 Z_Free( ev->evPtr );
00918 }
00919 eventTail++;
00920 }
00921
00922 eventHead++;
00923
00924 if ( time == 0 ) {
00925 time = Sys_Milliseconds();
00926 }
00927
00928 ev->evTime = time;
00929 ev->evType = type;
00930 ev->evValue = value;
00931 ev->evValue2 = value2;
00932 ev->evPtrLength = ptrLength;
00933 ev->evPtr = ptr;
00934 }
00935
00936
00937
00938
00939
00940
00941
00942 sysEvent_t Sys_GetEvent( void ) {
00943 MSG msg;
00944 sysEvent_t ev;
00945 char *s;
00946 msg_t netmsg;
00947 netadr_t adr;
00948
00949
00950 if ( eventHead > eventTail ) {
00951 eventTail++;
00952 return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
00953 }
00954
00955
00956 while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE)) {
00957 if ( !GetMessage (&msg, NULL, 0, 0) ) {
00958 Com_Quit_f();
00959 }
00960
00961
00962 g_wv.sysMsgTime = msg.time;
00963
00964 TranslateMessage (&msg);
00965 DispatchMessage (&msg);
00966 }
00967
00968
00969 s = Sys_ConsoleInput();
00970 if ( s ) {
00971 char *b;
00972 int len;
00973
00974 len = strlen( s ) + 1;
00975 b = Z_Malloc( len );
00976 Q_strncpyz( b, s, len-1 );
00977 Sys_QueEvent( 0, SE_CONSOLE, 0, 0, len, b );
00978 }
00979
00980
00981 MSG_Init( &netmsg, sys_packetReceived, sizeof( sys_packetReceived ) );
00982 if ( Sys_GetPacket ( &adr, &netmsg ) ) {
00983 netadr_t *buf;
00984 int len;
00985
00986
00987
00988 len = sizeof( netadr_t ) + netmsg.cursize - netmsg.readcount;
00989 buf = Z_Malloc( len );
00990 *buf = adr;
00991 memcpy( buf+1, &netmsg.data[netmsg.readcount], netmsg.cursize - netmsg.readcount );
00992 Sys_QueEvent( 0, SE_PACKET, 0, 0, len, buf );
00993 }
00994
00995
00996 if ( eventHead > eventTail ) {
00997 eventTail++;
00998 return eventQue[ ( eventTail - 1 ) & MASK_QUED_EVENTS ];
00999 }
01000
01001
01002
01003 memset( &ev, 0, sizeof( ev ) );
01004 ev.evTime = timeGetTime();
01005
01006 return ev;
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 void Sys_In_Restart_f( void ) {
01019 IN_Shutdown();
01020 IN_Init();
01021 }
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031 void Sys_Net_Restart_f( void ) {
01032 NET_Restart();
01033 }
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044 #define OSR2_BUILD_NUMBER 1111
01045 #define WIN98_BUILD_NUMBER 1998
01046
01047 void Sys_Init( void ) {
01048 int cpuid;
01049
01050
01051
01052 timeBeginPeriod( 1 );
01053
01054 Cmd_AddCommand ("in_restart", Sys_In_Restart_f);
01055 Cmd_AddCommand ("net_restart", Sys_Net_Restart_f);
01056
01057 g_wv.osversion.dwOSVersionInfoSize = sizeof( g_wv.osversion );
01058
01059 if (!GetVersionEx (&g_wv.osversion))
01060 Sys_Error ("Couldn't get OS info");
01061
01062 if (g_wv.osversion.dwMajorVersion < 4)
01063 Sys_Error ("Quake3 requires Windows version 4 or greater");
01064 if (g_wv.osversion.dwPlatformId == VER_PLATFORM_WIN32s)
01065 Sys_Error ("Quake3 doesn't run on Win32s");
01066
01067 if ( g_wv.osversion.dwPlatformId == VER_PLATFORM_WIN32_NT )
01068 {
01069 Cvar_Set( "arch", "winnt" );
01070 }
01071 else if ( g_wv.osversion.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
01072 {
01073 if ( LOWORD( g_wv.osversion.dwBuildNumber ) >= WIN98_BUILD_NUMBER )
01074 {
01075 Cvar_Set( "arch", "win98" );
01076 }
01077 else if ( LOWORD( g_wv.osversion.dwBuildNumber ) >= OSR2_BUILD_NUMBER )
01078 {
01079 Cvar_Set( "arch", "win95 osr2.x" );
01080 }
01081 else
01082 {
01083 Cvar_Set( "arch", "win95" );
01084 }
01085 }
01086 else
01087 {
01088 Cvar_Set( "arch", "unknown Windows variant" );
01089 }
01090
01091
01092 Cvar_Get( "win_hinstance", va("%i", (int)g_wv.hInstance), CVAR_ROM );
01093 Cvar_Get( "win_wndproc", va("%i", (int)MainWndProc), CVAR_ROM );
01094
01095
01096
01097
01098 Cvar_Get( "sys_cpustring", "detect", 0 );
01099 if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring"), "detect" ) )
01100 {
01101 Com_Printf( "...detecting CPU, found " );
01102
01103 cpuid = Sys_GetProcessorId();
01104
01105 switch ( cpuid )
01106 {
01107 case CPUID_GENERIC:
01108 Cvar_Set( "sys_cpustring", "generic" );
01109 break;
01110 case CPUID_INTEL_UNSUPPORTED:
01111 Cvar_Set( "sys_cpustring", "x86 (pre-Pentium)" );
01112 break;
01113 case CPUID_INTEL_PENTIUM:
01114 Cvar_Set( "sys_cpustring", "x86 (P5/PPro, non-MMX)" );
01115 break;
01116 case CPUID_INTEL_MMX:
01117 Cvar_Set( "sys_cpustring", "x86 (P5/Pentium2, MMX)" );
01118 break;
01119 case CPUID_INTEL_KATMAI:
01120 Cvar_Set( "sys_cpustring", "Intel Pentium III" );
01121 break;
01122 case CPUID_AMD_3DNOW:
01123 Cvar_Set( "sys_cpustring", "AMD w/ 3DNow!" );
01124 break;
01125 case CPUID_AXP:
01126 Cvar_Set( "sys_cpustring", "Alpha AXP" );
01127 break;
01128 default:
01129 Com_Error( ERR_FATAL, "Unknown cpu type %d\n", cpuid );
01130 break;
01131 }
01132 }
01133 else
01134 {
01135 Com_Printf( "...forcing CPU type to " );
01136 if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "generic" ) )
01137 {
01138 cpuid = CPUID_GENERIC;
01139 }
01140 else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "x87" ) )
01141 {
01142 cpuid = CPUID_INTEL_PENTIUM;
01143 }
01144 else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "mmx" ) )
01145 {
01146 cpuid = CPUID_INTEL_MMX;
01147 }
01148 else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "3dnow" ) )
01149 {
01150 cpuid = CPUID_AMD_3DNOW;
01151 }
01152 else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "PentiumIII" ) )
01153 {
01154 cpuid = CPUID_INTEL_KATMAI;
01155 }
01156 else if ( !Q_stricmp( Cvar_VariableString( "sys_cpustring" ), "axp" ) )
01157 {
01158 cpuid = CPUID_AXP;
01159 }
01160 else
01161 {
01162 Com_Printf( "WARNING: unknown sys_cpustring '%s'\n", Cvar_VariableString( "sys_cpustring" ) );
01163 cpuid = CPUID_GENERIC;
01164 }
01165 }
01166 Cvar_SetValue( "sys_cpuid", cpuid );
01167 Com_Printf( "%s\n", Cvar_VariableString( "sys_cpustring" ) );
01168
01169 Cvar_Set( "username", Sys_GetCurrentUser() );
01170
01171 IN_Init();
01172 }
01173
01174
01175
01176
01177 int totalMsec, countMsec;
01178
01179
01180
01181
01182
01183
01184
01185 int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
01186 char cwd[MAX_OSPATH];
01187 int startTime, endTime;
01188
01189
01190 if ( hPrevInstance ) {
01191 return 0;
01192 }
01193
01194 g_wv.hInstance = hInstance;
01195 Q_strncpyz( sys_cmdline, lpCmdLine, sizeof( sys_cmdline ) );
01196
01197
01198 Sys_CreateConsole();
01199
01200
01201 SetErrorMode( SEM_FAILCRITICALERRORS );
01202
01203
01204 Sys_Milliseconds();
01205 #if 0
01206
01207 Sys_ScanForCD();
01208 #endif
01209
01210 Sys_InitStreamThread();
01211
01212 Com_Init( sys_cmdline );
01213 NET_Init();
01214
01215 _getcwd (cwd, sizeof(cwd));
01216 Com_Printf("Working directory: %s\n", cwd);
01217
01218
01219
01220 if ( !com_dedicated->integer && !com_viewlog->integer ) {
01221 Sys_ShowConsole( 0, qfalse );
01222 }
01223
01224
01225 while( 1 ) {
01226
01227 if ( g_wv.isMinimized || ( com_dedicated && com_dedicated->integer ) ) {
01228 Sleep( 5 );
01229 }
01230
01231
01232
01233
01234
01235
01236
01237 startTime = Sys_Milliseconds();
01238
01239
01240 IN_Frame();
01241
01242
01243 Com_Frame();
01244
01245 endTime = Sys_Milliseconds();
01246 totalMsec += endTime - startTime;
01247 countMsec++;
01248 }
01249
01250
01251 }
01252
01253