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.h"
00025
00026 #include "../botlib/botlib.h"
00027
00028 extern botlib_export_t *botlib_export;
00029
00030 extern qboolean loadCamera(const char *name);
00031 extern void startCamera(int time);
00032 extern qboolean getCameraInfo(int time, vec3_t *origin, vec3_t *angles);
00033
00034
00035
00036
00037
00038
00039 void CL_GetGameState( gameState_t *gs ) {
00040 *gs = cl.gameState;
00041 }
00042
00043
00044
00045
00046
00047
00048 void CL_GetGlconfig( glconfig_t *glconfig ) {
00049 *glconfig = cls.glconfig;
00050 }
00051
00052
00053
00054
00055
00056
00057
00058 qboolean CL_GetUserCmd( int cmdNumber, usercmd_t *ucmd ) {
00059
00060
00061
00062 if ( cmdNumber > cl.cmdNumber ) {
00063 Com_Error( ERR_DROP, "CL_GetUserCmd: %i >= %i", cmdNumber, cl.cmdNumber );
00064 }
00065
00066
00067
00068 if ( cmdNumber <= cl.cmdNumber - CMD_BACKUP ) {
00069 return qfalse;
00070 }
00071
00072 *ucmd = cl.cmds[ cmdNumber & CMD_MASK ];
00073
00074 return qtrue;
00075 }
00076
00077 int CL_GetCurrentCmdNumber( void ) {
00078 return cl.cmdNumber;
00079 }
00080
00081
00082
00083
00084
00085
00086
00087 qboolean CL_GetParseEntityState( int parseEntityNumber, entityState_t *state ) {
00088
00089 if ( parseEntityNumber >= cl.parseEntitiesNum ) {
00090 Com_Error( ERR_DROP, "CL_GetParseEntityState: %i >= %i",
00091 parseEntityNumber, cl.parseEntitiesNum );
00092 }
00093
00094
00095 if ( parseEntityNumber <= cl.parseEntitiesNum - MAX_PARSE_ENTITIES ) {
00096 return qfalse;
00097 }
00098
00099 *state = cl.parseEntities[ parseEntityNumber & ( MAX_PARSE_ENTITIES - 1 ) ];
00100 return qtrue;
00101 }
00102
00103
00104
00105
00106
00107
00108 void CL_GetCurrentSnapshotNumber( int *snapshotNumber, int *serverTime ) {
00109 *snapshotNumber = cl.snap.messageNum;
00110 *serverTime = cl.snap.serverTime;
00111 }
00112
00113
00114
00115
00116
00117
00118 qboolean CL_GetSnapshot( int snapshotNumber, snapshot_t *snapshot ) {
00119 clSnapshot_t *clSnap;
00120 int i, count;
00121
00122 if ( snapshotNumber > cl.snap.messageNum ) {
00123 Com_Error( ERR_DROP, "CL_GetSnapshot: snapshotNumber > cl.snapshot.messageNum" );
00124 }
00125
00126
00127 if ( cl.snap.messageNum - snapshotNumber >= PACKET_BACKUP ) {
00128 return qfalse;
00129 }
00130
00131
00132 clSnap = &cl.snapshots[snapshotNumber & PACKET_MASK];
00133 if ( !clSnap->valid ) {
00134 return qfalse;
00135 }
00136
00137
00138
00139 if ( cl.parseEntitiesNum - clSnap->parseEntitiesNum >= MAX_PARSE_ENTITIES ) {
00140 return qfalse;
00141 }
00142
00143
00144 snapshot->snapFlags = clSnap->snapFlags;
00145 snapshot->serverCommandSequence = clSnap->serverCommandNum;
00146 snapshot->ping = clSnap->ping;
00147 snapshot->serverTime = clSnap->serverTime;
00148 Com_Memcpy( snapshot->areamask, clSnap->areamask, sizeof( snapshot->areamask ) );
00149 snapshot->ps = clSnap->ps;
00150 count = clSnap->numEntities;
00151 if ( count > MAX_ENTITIES_IN_SNAPSHOT ) {
00152 Com_DPrintf( "CL_GetSnapshot: truncated %i entities to %i\n", count, MAX_ENTITIES_IN_SNAPSHOT );
00153 count = MAX_ENTITIES_IN_SNAPSHOT;
00154 }
00155 snapshot->numEntities = count;
00156 for ( i = 0 ; i < count ; i++ ) {
00157 snapshot->entities[i] =
00158 cl.parseEntities[ ( clSnap->parseEntitiesNum + i ) & (MAX_PARSE_ENTITIES-1) ];
00159 }
00160
00161
00162
00163 return qtrue;
00164 }
00165
00166
00167
00168
00169
00170
00171 void CL_SetUserCmdValue( int userCmdValue, float sensitivityScale ) {
00172 cl.cgameUserCmdValue = userCmdValue;
00173 cl.cgameSensitivity = sensitivityScale;
00174 }
00175
00176
00177
00178
00179
00180
00181 void CL_AddCgameCommand( const char *cmdName ) {
00182 Cmd_AddCommand( cmdName, NULL );
00183 }
00184
00185
00186
00187
00188
00189
00190 void CL_CgameError( const char *string ) {
00191 Com_Error( ERR_DROP, "%s", string );
00192 }
00193
00194
00195
00196
00197
00198
00199
00200 void CL_ConfigstringModified( void ) {
00201 char *old, *s;
00202 int i, index;
00203 char *dup;
00204 gameState_t oldGs;
00205 int len;
00206
00207 index = atoi( Cmd_Argv(1) );
00208 if ( index < 0 || index >= MAX_CONFIGSTRINGS ) {
00209 Com_Error( ERR_DROP, "configstring > MAX_CONFIGSTRINGS" );
00210 }
00211
00212 s = Cmd_ArgsFrom(2);
00213
00214 old = cl.gameState.stringData + cl.gameState.stringOffsets[ index ];
00215 if ( !strcmp( old, s ) ) {
00216 return;
00217 }
00218
00219
00220 oldGs = cl.gameState;
00221
00222 Com_Memset( &cl.gameState, 0, sizeof( cl.gameState ) );
00223
00224
00225 cl.gameState.dataCount = 1;
00226
00227 for ( i = 0 ; i < MAX_CONFIGSTRINGS ; i++ ) {
00228 if ( i == index ) {
00229 dup = s;
00230 } else {
00231 dup = oldGs.stringData + oldGs.stringOffsets[ i ];
00232 }
00233 if ( !dup[0] ) {
00234 continue;
00235 }
00236
00237 len = strlen( dup );
00238
00239 if ( len + 1 + cl.gameState.dataCount > MAX_GAMESTATE_CHARS ) {
00240 Com_Error( ERR_DROP, "MAX_GAMESTATE_CHARS exceeded" );
00241 }
00242
00243
00244 cl.gameState.stringOffsets[ i ] = cl.gameState.dataCount;
00245 Com_Memcpy( cl.gameState.stringData + cl.gameState.dataCount, dup, len + 1 );
00246 cl.gameState.dataCount += len + 1;
00247 }
00248
00249 if ( index == CS_SYSTEMINFO ) {
00250
00251 CL_SystemInfoChanged();
00252 }
00253
00254 }
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 qboolean CL_GetServerCommand( int serverCommandNumber ) {
00265 char *s;
00266 char *cmd;
00267 static char bigConfigString[BIG_INFO_STRING];
00268 int argc;
00269
00270
00271 if ( serverCommandNumber <= clc.serverCommandSequence - MAX_RELIABLE_COMMANDS ) {
00272
00273
00274 if ( clc.demoplaying )
00275 return qfalse;
00276 Com_Error( ERR_DROP, "CL_GetServerCommand: a reliable command was cycled out" );
00277 return qfalse;
00278 }
00279
00280 if ( serverCommandNumber > clc.serverCommandSequence ) {
00281 Com_Error( ERR_DROP, "CL_GetServerCommand: requested a command not received" );
00282 return qfalse;
00283 }
00284
00285 s = clc.serverCommands[ serverCommandNumber & ( MAX_RELIABLE_COMMANDS - 1 ) ];
00286 clc.lastExecutedServerCommand = serverCommandNumber;
00287
00288 Com_DPrintf( "serverCommand: %i : %s\n", serverCommandNumber, s );
00289
00290 rescan:
00291 Cmd_TokenizeString( s );
00292 cmd = Cmd_Argv(0);
00293 argc = Cmd_Argc();
00294
00295 if ( !strcmp( cmd, "disconnect" ) ) {
00296
00297
00298 if ( argc >= 2 )
00299 Com_Error (ERR_SERVERDISCONNECT, va( "Server Disconnected - %s", Cmd_Argv( 1 ) ) );
00300 else
00301 Com_Error (ERR_SERVERDISCONNECT,"Server disconnected\n");
00302 }
00303
00304 if ( !strcmp( cmd, "bcs0" ) ) {
00305 Com_sprintf( bigConfigString, BIG_INFO_STRING, "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2) );
00306 return qfalse;
00307 }
00308
00309 if ( !strcmp( cmd, "bcs1" ) ) {
00310 s = Cmd_Argv(2);
00311 if( strlen(bigConfigString) + strlen(s) >= BIG_INFO_STRING ) {
00312 Com_Error( ERR_DROP, "bcs exceeded BIG_INFO_STRING" );
00313 }
00314 strcat( bigConfigString, s );
00315 return qfalse;
00316 }
00317
00318 if ( !strcmp( cmd, "bcs2" ) ) {
00319 s = Cmd_Argv(2);
00320 if( strlen(bigConfigString) + strlen(s) + 1 >= BIG_INFO_STRING ) {
00321 Com_Error( ERR_DROP, "bcs exceeded BIG_INFO_STRING" );
00322 }
00323 strcat( bigConfigString, s );
00324 strcat( bigConfigString, "\"" );
00325 s = bigConfigString;
00326 goto rescan;
00327 }
00328
00329 if ( !strcmp( cmd, "cs" ) ) {
00330 CL_ConfigstringModified();
00331
00332 Cmd_TokenizeString( s );
00333 return qtrue;
00334 }
00335
00336 if ( !strcmp( cmd, "map_restart" ) ) {
00337
00338
00339 Con_ClearNotify();
00340 Com_Memset( cl.cmds, 0, sizeof( cl.cmds ) );
00341 return qtrue;
00342 }
00343
00344
00345
00346
00347
00348
00349 if ( !strcmp( cmd, "clientLevelShot" ) ) {
00350
00351
00352
00353 if ( !com_sv_running->integer ) {
00354 return qfalse;
00355 }
00356
00357 Con_Close();
00358
00359 Cbuf_AddText( "wait ; wait ; wait ; wait ; screenshot levelshot\n" );
00360 return qtrue;
00361 }
00362
00363
00364
00365
00366 return qtrue;
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 void CL_CM_LoadMap( const char *mapname ) {
00378 int checksum;
00379
00380 CM_LoadMap( mapname, qtrue, &checksum );
00381 }
00382
00383
00384
00385
00386
00387
00388
00389 void CL_ShutdownCGame( void ) {
00390 cls.keyCatchers &= ~KEYCATCH_CGAME;
00391 cls.cgameStarted = qfalse;
00392 if ( !cgvm ) {
00393 return;
00394 }
00395 VM_Call( cgvm, CG_SHUTDOWN );
00396 VM_Free( cgvm );
00397 cgvm = NULL;
00398 }
00399
00400 static int FloatAsInt( float f ) {
00401 int temp;
00402
00403 *(float *)&temp = f;
00404
00405 return temp;
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415 intptr_t CL_CgameSystemCalls( intptr_t *args ) {
00416 switch( args[0] ) {
00417 case CG_PRINT:
00418 Com_Printf( "%s", (const char*)VMA(1) );
00419 return 0;
00420 case CG_ERROR:
00421 Com_Error( ERR_DROP, "%s", (const char*)VMA(1) );
00422 return 0;
00423 case CG_MILLISECONDS:
00424 return Sys_Milliseconds();
00425 case CG_CVAR_REGISTER:
00426 Cvar_Register( VMA(1), VMA(2), VMA(3), args[4] );
00427 return 0;
00428 case CG_CVAR_UPDATE:
00429 Cvar_Update( VMA(1) );
00430 return 0;
00431 case CG_CVAR_SET:
00432 Cvar_Set( VMA(1), VMA(2) );
00433 return 0;
00434 case CG_CVAR_VARIABLESTRINGBUFFER:
00435 Cvar_VariableStringBuffer( VMA(1), VMA(2), args[3] );
00436 return 0;
00437 case CG_ARGC:
00438 return Cmd_Argc();
00439 case CG_ARGV:
00440 Cmd_ArgvBuffer( args[1], VMA(2), args[3] );
00441 return 0;
00442 case CG_ARGS:
00443 Cmd_ArgsBuffer( VMA(1), args[2] );
00444 return 0;
00445 case CG_FS_FOPENFILE:
00446 return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] );
00447 case CG_FS_READ:
00448 FS_Read2( VMA(1), args[2], args[3] );
00449 return 0;
00450 case CG_FS_WRITE:
00451 FS_Write( VMA(1), args[2], args[3] );
00452 return 0;
00453 case CG_FS_FCLOSEFILE:
00454 FS_FCloseFile( args[1] );
00455 return 0;
00456 case CG_FS_SEEK:
00457 return FS_Seek( args[1], args[2], args[3] );
00458 case CG_SENDCONSOLECOMMAND:
00459 Cbuf_AddText( VMA(1) );
00460 return 0;
00461 case CG_ADDCOMMAND:
00462 CL_AddCgameCommand( VMA(1) );
00463 return 0;
00464 case CG_REMOVECOMMAND:
00465 Cmd_RemoveCommand( VMA(1) );
00466 return 0;
00467 case CG_SENDCLIENTCOMMAND:
00468 CL_AddReliableCommand( VMA(1) );
00469 return 0;
00470 case CG_UPDATESCREEN:
00471
00472
00473
00474
00475
00476 SCR_UpdateScreen();
00477 return 0;
00478 case CG_CM_LOADMAP:
00479 CL_CM_LoadMap( VMA(1) );
00480 return 0;
00481 case CG_CM_NUMINLINEMODELS:
00482 return CM_NumInlineModels();
00483 case CG_CM_INLINEMODEL:
00484 return CM_InlineModel( args[1] );
00485 case CG_CM_TEMPBOXMODEL:
00486 return CM_TempBoxModel( VMA(1), VMA(2), qfalse );
00487 case CG_CM_TEMPCAPSULEMODEL:
00488 return CM_TempBoxModel( VMA(1), VMA(2), qtrue );
00489 case CG_CM_POINTCONTENTS:
00490 return CM_PointContents( VMA(1), args[2] );
00491 case CG_CM_TRANSFORMEDPOINTCONTENTS:
00492 return CM_TransformedPointContents( VMA(1), args[2], VMA(3), VMA(4) );
00493 case CG_CM_BOXTRACE:
00494 CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], qfalse );
00495 return 0;
00496 case CG_CM_CAPSULETRACE:
00497 CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], qtrue );
00498 return 0;
00499 case CG_CM_TRANSFORMEDBOXTRACE:
00500 CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), qfalse );
00501 return 0;
00502 case CG_CM_TRANSFORMEDCAPSULETRACE:
00503 CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), qtrue );
00504 return 0;
00505 case CG_CM_MARKFRAGMENTS:
00506 return re.MarkFragments( args[1], VMA(2), VMA(3), args[4], VMA(5), args[6], VMA(7) );
00507 case CG_S_STARTSOUND:
00508 S_StartSound( VMA(1), args[2], args[3], args[4] );
00509 return 0;
00510 case CG_S_STARTLOCALSOUND:
00511 S_StartLocalSound( args[1], args[2] );
00512 return 0;
00513 case CG_S_CLEARLOOPINGSOUNDS:
00514 S_ClearLoopingSounds(args[1]);
00515 return 0;
00516 case CG_S_ADDLOOPINGSOUND:
00517 S_AddLoopingSound( args[1], VMA(2), VMA(3), args[4] );
00518 return 0;
00519 case CG_S_ADDREALLOOPINGSOUND:
00520 S_AddRealLoopingSound( args[1], VMA(2), VMA(3), args[4] );
00521 return 0;
00522 case CG_S_STOPLOOPINGSOUND:
00523 S_StopLoopingSound( args[1] );
00524 return 0;
00525 case CG_S_UPDATEENTITYPOSITION:
00526 S_UpdateEntityPosition( args[1], VMA(2) );
00527 return 0;
00528 case CG_S_RESPATIALIZE:
00529 S_Respatialize( args[1], VMA(2), VMA(3), args[4] );
00530 return 0;
00531 case CG_S_REGISTERSOUND:
00532 return S_RegisterSound( VMA(1), args[2] );
00533 case CG_S_STARTBACKGROUNDTRACK:
00534 S_StartBackgroundTrack( VMA(1), VMA(2) );
00535 return 0;
00536 case CG_R_LOADWORLDMAP:
00537 re.LoadWorld( VMA(1) );
00538 return 0;
00539 case CG_R_REGISTERMODEL:
00540 return re.RegisterModel( VMA(1) );
00541 case CG_R_REGISTERSKIN:
00542 return re.RegisterSkin( VMA(1) );
00543 case CG_R_REGISTERSHADER:
00544 return re.RegisterShader( VMA(1) );
00545 case CG_R_REGISTERSHADERNOMIP:
00546 return re.RegisterShaderNoMip( VMA(1) );
00547 case CG_R_REGISTERFONT:
00548 re.RegisterFont( VMA(1), args[2], VMA(3));
00549 case CG_R_CLEARSCENE:
00550 re.ClearScene();
00551 return 0;
00552 case CG_R_ADDREFENTITYTOSCENE:
00553 re.AddRefEntityToScene( VMA(1) );
00554 return 0;
00555 case CG_R_ADDPOLYTOSCENE:
00556 re.AddPolyToScene( args[1], args[2], VMA(3), 1 );
00557 return 0;
00558 case CG_R_ADDPOLYSTOSCENE:
00559 re.AddPolyToScene( args[1], args[2], VMA(3), args[4] );
00560 return 0;
00561 case CG_R_LIGHTFORPOINT:
00562 return re.LightForPoint( VMA(1), VMA(2), VMA(3), VMA(4) );
00563 case CG_R_ADDLIGHTTOSCENE:
00564 re.AddLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
00565 return 0;
00566 case CG_R_ADDADDITIVELIGHTTOSCENE:
00567 re.AddAdditiveLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) );
00568 return 0;
00569 case CG_R_RENDERSCENE:
00570 re.RenderScene( VMA(1) );
00571 return 0;
00572 case CG_R_SETCOLOR:
00573 re.SetColor( VMA(1) );
00574 return 0;
00575 case CG_R_DRAWSTRETCHPIC:
00576 re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9] );
00577 return 0;
00578 case CG_R_MODELBOUNDS:
00579 re.ModelBounds( args[1], VMA(2), VMA(3) );
00580 return 0;
00581 case CG_R_LERPTAG:
00582 return re.LerpTag( VMA(1), args[2], args[3], args[4], VMF(5), VMA(6) );
00583 case CG_GETGLCONFIG:
00584 CL_GetGlconfig( VMA(1) );
00585 return 0;
00586 case CG_GETGAMESTATE:
00587 CL_GetGameState( VMA(1) );
00588 return 0;
00589 case CG_GETCURRENTSNAPSHOTNUMBER:
00590 CL_GetCurrentSnapshotNumber( VMA(1), VMA(2) );
00591 return 0;
00592 case CG_GETSNAPSHOT:
00593 return CL_GetSnapshot( args[1], VMA(2) );
00594 case CG_GETSERVERCOMMAND:
00595 return CL_GetServerCommand( args[1] );
00596 case CG_GETCURRENTCMDNUMBER:
00597 return CL_GetCurrentCmdNumber();
00598 case CG_GETUSERCMD:
00599 return CL_GetUserCmd( args[1], VMA(2) );
00600 case CG_SETUSERCMDVALUE:
00601 CL_SetUserCmdValue( args[1], VMF(2) );
00602 return 0;
00603 case CG_MEMORY_REMAINING:
00604 return Hunk_MemoryRemaining();
00605 case CG_KEY_ISDOWN:
00606 return Key_IsDown( args[1] );
00607 case CG_KEY_GETCATCHER:
00608 return Key_GetCatcher();
00609 case CG_KEY_SETCATCHER:
00610 Key_SetCatcher( args[1] );
00611 return 0;
00612 case CG_KEY_GETKEY:
00613 return Key_GetKey( VMA(1) );
00614
00615
00616
00617 case CG_MEMSET:
00618 Com_Memset( VMA(1), args[2], args[3] );
00619 return 0;
00620 case CG_MEMCPY:
00621 Com_Memcpy( VMA(1), VMA(2), args[3] );
00622 return 0;
00623 case CG_STRNCPY:
00624 strncpy( VMA(1), VMA(2), args[3] );
00625 return args[1];
00626 case CG_SIN:
00627 return FloatAsInt( sin( VMF(1) ) );
00628 case CG_COS:
00629 return FloatAsInt( cos( VMF(1) ) );
00630 case CG_ATAN2:
00631 return FloatAsInt( atan2( VMF(1), VMF(2) ) );
00632 case CG_SQRT:
00633 return FloatAsInt( sqrt( VMF(1) ) );
00634 case CG_FLOOR:
00635 return FloatAsInt( floor( VMF(1) ) );
00636 case CG_CEIL:
00637 return FloatAsInt( ceil( VMF(1) ) );
00638 case CG_ACOS:
00639 return FloatAsInt( Q_acos( VMF(1) ) );
00640
00641 case CG_PC_ADD_GLOBAL_DEFINE:
00642 return botlib_export->PC_AddGlobalDefine( VMA(1) );
00643 case CG_PC_LOAD_SOURCE:
00644 return botlib_export->PC_LoadSourceHandle( VMA(1) );
00645 case CG_PC_FREE_SOURCE:
00646 return botlib_export->PC_FreeSourceHandle( args[1] );
00647 case CG_PC_READ_TOKEN:
00648 return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) );
00649 case CG_PC_SOURCE_FILE_AND_LINE:
00650 return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) );
00651
00652 case CG_S_STOPBACKGROUNDTRACK:
00653 S_StopBackgroundTrack();
00654 return 0;
00655
00656 case CG_REAL_TIME:
00657 return Com_RealTime( VMA(1) );
00658 case CG_SNAPVECTOR:
00659 Sys_SnapVector( VMA(1) );
00660 return 0;
00661
00662 case CG_CIN_PLAYCINEMATIC:
00663 return CIN_PlayCinematic(VMA(1), args[2], args[3], args[4], args[5], args[6]);
00664
00665 case CG_CIN_STOPCINEMATIC:
00666 return CIN_StopCinematic(args[1]);
00667
00668 case CG_CIN_RUNCINEMATIC:
00669 return CIN_RunCinematic(args[1]);
00670
00671 case CG_CIN_DRAWCINEMATIC:
00672 CIN_DrawCinematic(args[1]);
00673 return 0;
00674
00675 case CG_CIN_SETEXTENTS:
00676 CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]);
00677 return 0;
00678
00679 case CG_R_REMAP_SHADER:
00680 re.RemapShader( VMA(1), VMA(2), VMA(3) );
00681 return 0;
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 case CG_GET_ENTITY_TOKEN:
00695 return re.GetEntityToken( VMA(1), args[2] );
00696 case CG_R_INPVS:
00697 return re.inPVS( VMA(1), VMA(2) );
00698
00699 default:
00700 assert(0);
00701 Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] );
00702 }
00703 return 0;
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 void CL_InitCGame( void ) {
00715 const char *info;
00716 const char *mapname;
00717 int t1, t2;
00718 vmInterpret_t interpret;
00719
00720 t1 = Sys_Milliseconds();
00721
00722
00723 Con_Close();
00724
00725
00726 info = cl.gameState.stringData + cl.gameState.stringOffsets[ CS_SERVERINFO ];
00727 mapname = Info_ValueForKey( info, "mapname" );
00728 Com_sprintf( cl.mapname, sizeof( cl.mapname ), "maps/%s.bsp", mapname );
00729
00730
00731 if ( cl_connectedToPureServer != 0 ) {
00732
00733 interpret = VMI_COMPILED;
00734 }
00735 else {
00736 interpret = Cvar_VariableValue( "vm_cgame" );
00737 }
00738 cgvm = VM_Create( "cgame", CL_CgameSystemCalls, interpret );
00739 if ( !cgvm ) {
00740 Com_Error( ERR_DROP, "VM_Create on cgame failed" );
00741 }
00742 cls.state = CA_LOADING;
00743
00744
00745
00746
00747 VM_Call( cgvm, CG_INIT, clc.serverMessageSequence, clc.lastExecutedServerCommand, clc.clientNum );
00748
00749
00750 if ( !clc.demoplaying && !cl_connectedToCheatServer )
00751 Cvar_SetCheatState();
00752
00753
00754
00755 cls.state = CA_PRIMED;
00756
00757 t2 = Sys_Milliseconds();
00758
00759 Com_Printf( "CL_InitCGame: %5.2f seconds\n", (t2-t1)/1000.0 );
00760
00761
00762
00763 re.EndRegistration();
00764
00765
00766 if (!Sys_LowPhysicalMemory()) {
00767 Com_TouchMemory();
00768 }
00769
00770
00771 Con_ClearNotify ();
00772 }
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 qboolean CL_GameCommand( void ) {
00783 if ( !cgvm ) {
00784 return qfalse;
00785 }
00786
00787 return VM_Call( cgvm, CG_CONSOLE_COMMAND );
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797 void CL_CGameRendering( stereoFrame_t stereo ) {
00798 VM_Call( cgvm, CG_DRAW_ACTIVE_FRAME, cl.serverTime, stereo, clc.demoplaying );
00799 VM_Debug( 0 );
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 #define RESET_TIME 500
00824
00825 void CL_AdjustTimeDelta( void ) {
00826 int resetTime;
00827 int newDelta;
00828 int deltaDelta;
00829
00830 cl.newSnapshots = qfalse;
00831
00832
00833 if ( clc.demoplaying ) {
00834 return;
00835 }
00836
00837
00838 if ( com_sv_running->integer ) {
00839 resetTime = 100;
00840 } else {
00841 resetTime = RESET_TIME;
00842 }
00843
00844 newDelta = cl.snap.serverTime - cls.realtime;
00845 deltaDelta = abs( newDelta - cl.serverTimeDelta );
00846
00847 if ( deltaDelta > RESET_TIME ) {
00848 cl.serverTimeDelta = newDelta;
00849 cl.oldServerTime = cl.snap.serverTime;
00850 cl.serverTime = cl.snap.serverTime;
00851 if ( cl_showTimeDelta->integer ) {
00852 Com_Printf( "<RESET> " );
00853 }
00854 } else if ( deltaDelta > 100 ) {
00855
00856 if ( cl_showTimeDelta->integer ) {
00857 Com_Printf( "<FAST> " );
00858 }
00859 cl.serverTimeDelta = ( cl.serverTimeDelta + newDelta ) >> 1;
00860 } else {
00861
00862
00863
00864
00865
00866 if ( com_timescale->value == 0 || com_timescale->value == 1 ) {
00867 if ( cl.extrapolatedSnapshot ) {
00868 cl.extrapolatedSnapshot = qfalse;
00869 cl.serverTimeDelta -= 2;
00870 } else {
00871
00872 cl.serverTimeDelta++;
00873 }
00874 }
00875 }
00876
00877 if ( cl_showTimeDelta->integer ) {
00878 Com_Printf( "%i ", cl.serverTimeDelta );
00879 }
00880 }
00881
00882
00883
00884
00885
00886
00887
00888 void CL_FirstSnapshot( void ) {
00889
00890 if ( cl.snap.snapFlags & SNAPFLAG_NOT_ACTIVE ) {
00891 return;
00892 }
00893 cls.state = CA_ACTIVE;
00894
00895
00896 cl.serverTimeDelta = cl.snap.serverTime - cls.realtime;
00897 cl.oldServerTime = cl.snap.serverTime;
00898
00899 clc.timeDemoBaseTime = cl.snap.serverTime;
00900
00901
00902
00903
00904
00905 if ( cl_activeAction->string[0] ) {
00906 Cbuf_AddText( cl_activeAction->string );
00907 Cvar_Set( "activeAction", "" );
00908 }
00909
00910 Sys_BeginProfiling();
00911 }
00912
00913
00914
00915
00916
00917
00918 void CL_SetCGameTime( void ) {
00919
00920 if ( cls.state != CA_ACTIVE ) {
00921 if ( cls.state != CA_PRIMED ) {
00922 return;
00923 }
00924 if ( clc.demoplaying ) {
00925
00926
00927 if ( !clc.firstDemoFrameSkipped ) {
00928 clc.firstDemoFrameSkipped = qtrue;
00929 return;
00930 }
00931 CL_ReadDemoMessage();
00932 }
00933 if ( cl.newSnapshots ) {
00934 cl.newSnapshots = qfalse;
00935 CL_FirstSnapshot();
00936 }
00937 if ( cls.state != CA_ACTIVE ) {
00938 return;
00939 }
00940 }
00941
00942
00943 if ( !cl.snap.valid ) {
00944 Com_Error( ERR_DROP, "CL_SetCGameTime: !cl.snap.valid" );
00945 }
00946
00947
00948 if ( sv_paused->integer && CL_CheckPaused() && com_sv_running->integer ) {
00949
00950 return;
00951 }
00952
00953 if ( cl.snap.serverTime < cl.oldFrameServerTime ) {
00954 Com_Error( ERR_DROP, "cl.snap.serverTime < cl.oldFrameServerTime" );
00955 }
00956 cl.oldFrameServerTime = cl.snap.serverTime;
00957
00958
00959
00960
00961 if ( clc.demoplaying && cl_freezeDemo->integer ) {
00962
00963
00964 } else {
00965
00966
00967
00968 int tn;
00969
00970 tn = cl_timeNudge->integer;
00971 if (tn<-30) {
00972 tn = -30;
00973 } else if (tn>30) {
00974 tn = 30;
00975 }
00976
00977 cl.serverTime = cls.realtime + cl.serverTimeDelta - tn;
00978
00979
00980
00981 if ( cl.serverTime < cl.oldServerTime ) {
00982 cl.serverTime = cl.oldServerTime;
00983 }
00984 cl.oldServerTime = cl.serverTime;
00985
00986
00987
00988 if ( cls.realtime + cl.serverTimeDelta >= cl.snap.serverTime - 5 ) {
00989 cl.extrapolatedSnapshot = qtrue;
00990 }
00991 }
00992
00993
00994
00995
00996 if ( cl.newSnapshots ) {
00997 CL_AdjustTimeDelta();
00998 }
00999
01000 if ( !clc.demoplaying ) {
01001 return;
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012 if ( cl_timedemo->integer ) {
01013 if (!clc.timeDemoStart) {
01014 clc.timeDemoStart = Sys_Milliseconds();
01015 }
01016 clc.timeDemoFrames++;
01017 cl.serverTime = clc.timeDemoBaseTime + clc.timeDemoFrames * 50;
01018 }
01019
01020 while ( cl.serverTime >= cl.snap.serverTime ) {
01021
01022
01023 CL_ReadDemoMessage();
01024 if ( cls.state != CA_ACTIVE ) {
01025 return;
01026 }
01027 }
01028
01029 }
01030
01031
01032