static void CLQW_CalcModelChecksum( const char* modelName, const char* cvarName ) { idList<byte> buffer; if ( !FS_ReadFile( modelName, buffer ) ) { common->Error( "Couldn't load %s", modelName ); } unsigned short crc; CRC_Init( &crc ); for ( int i = 0; i < buffer.Num(); i++ ) { CRC_ProcessByte( &crc, buffer[ i ] ); } char st[ 40 ]; sprintf( st, "%d", ( int )crc ); Info_SetValueForKey( cls.qh_userinfo, cvarName, st, MAX_INFO_STRING_QW, 64, 64, true, false ); sprintf( st, "setinfo %s %d", cvarName, ( int )crc ); CL_AddReliableCommand( st ); }
static void CG_ScoresDown_f( void ) { if ( cg.scoresRequestTime + 2000 < cg.time ) { // the scores are more than two seconds out of data, // so request New ones cg.scoresRequestTime = cg.time; CL_AddReliableCommand( "score" ); // leave the current scores up if they were already // displayed, but if this is the first hit, clear them out if ( !cg.showScores ) { cg.showScores = true; cg.numScores = 0; } } else { // show the cached contents even if they just pressed if it // is within two seconds cg.showScores = true; } }
/* ===================== CL_Disconnect Called when a connection, or cinematic is being terminated. Goes from a connected state to either a menu state or a console state Sends a disconnect message to the server This is also called on Com_Error and Com_Quit, so it shouldn't cause any errors ===================== */ void CL_Disconnect( void ) { int i; if ( !com_cl_running || !com_cl_running->integer ) { return; } if (cls.uiStarted) UI_SetActiveMenu( NULL,NULL ); SCR_StopCinematic (); S_ClearSoundBuffer(); // send a disconnect message to the server // send it a few times in case one is dropped if ( cls.state >= CA_CONNECTED ) { CL_AddReliableCommand( "disconnect" ); CL_WritePacket(); CL_WritePacket(); CL_WritePacket(); } CL_ClearState (); // wipe the client connection for ( i = 0 ; i < MAX_RELIABLE_COMMANDS ; i++ ) { if ( clc.reliableCommands[i] ) { Z_Free( clc.reliableCommands[i] ); } } memset( &clc, 0, sizeof( clc ) ); cls.state = CA_DISCONNECTED; // allow cheats locally Cvar_Set( "timescale", "1" );//jic we were skipping Cvar_Set( "skippingCinematic", "0" );//jic we were skipping }
static void CLQW_ParseModelList( QMsg& message ) { // precache models and note certain default indexes int nummodels = message.ReadByte(); for (;; ) { const char* str = message.ReadString2(); if ( !str[ 0 ] ) { break; } nummodels++; if ( nummodels == MAX_MODELS_Q1 ) { common->Error( "Server sent too many model_precache" ); } String::Cpy( cl.qh_model_name[ nummodels ], str ); if ( !String::Cmp( cl.qh_model_name[ nummodels ],"progs/spike.mdl" ) ) { clq1_spikeindex = nummodels; } if ( !String::Cmp( cl.qh_model_name[ nummodels ],"progs/player.mdl" ) ) { clq1_playerindex = nummodels; } if ( !String::Cmp( cl.qh_model_name[ nummodels ],"progs/flag.mdl" ) ) { clqw_flagindex = nummodels; } } int n = message.ReadByte(); if ( n ) { CL_AddReliableCommand( va( "modellist %i %i", cl.servercount, n ) ); return; } clc.downloadNumber = 0; clc.downloadType = dl_model; CLQW_Model_NextDownload(); }
/* =================== CL_ForwardCommandToServer adds the current command line as a clientCommand things like godmode, noclip, etc, are commands directed to the server, so when they are typed in at the console, they will need to be forwarded. =================== */ void CL_ForwardCommandToServer( void ) { char *cmd; char string[MAX_STRING_CHARS]; cmd = Cmd_Argv(0); // ignore key up commands if ( cmd[0] == '-' ) { return; } if ( cls.state != CA_ACTIVE || cmd[0] == '+' ) { Com_Printf ("Unknown command \"%s\"\n", cmd); return; } if ( Cmd_Argc() > 1 ) { Com_sprintf( string, sizeof(string), "%s %s", cmd, Cmd_Args() ); } else { Q_strncpyz( string, cmd, sizeof(string) ); } CL_AddReliableCommand( string ); }
void CL_cURL_BeginDownload( const char *localName, const char *remoteURL ) { clc.cURLUsed = qtrue; Com_Printf("URL: %s\n", remoteURL); Com_DPrintf("***** CL_cURL_BeginDownload *****\n" "Localname: %s\n" "RemoteURL: %s\n" "****************************\n", localName, remoteURL); CL_cURL_Cleanup(); Q_strncpyz(clc.downloadURL, remoteURL, sizeof(clc.downloadURL)); Q_strncpyz(clc.downloadName, localName, sizeof(clc.downloadName)); Com_sprintf(clc.downloadTempName, sizeof(clc.downloadTempName), "%s.tmp", localName); // Set so UI gets access to it Cvar_Set("cl_downloadName", localName); Cvar_Set("cl_downloadSize", "0"); Cvar_Set("cl_downloadCount", "0"); Cvar_SetValue("cl_downloadTime", cls.realtime); clc.downloadBlock = 0; // Starting new file clc.downloadCount = 0; clc.downloadCURL = qcurl_easy_init(); if(!clc.downloadCURL) { Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_easy_init() " "failed\n"); return; } clc.download = FS_SV_FOpenFileWrite(clc.downloadTempName); if(!clc.download) { Com_Error(ERR_DROP, "CL_cURL_BeginDownload: failed to open " "%s for writing\n", clc.downloadTempName); return; } qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, clc.download); if(com_developer->integer) qcurl_easy_setopt(clc.downloadCURL, CURLOPT_VERBOSE, 1); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_URL, clc.downloadURL); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_TRANSFERTEXT, 0); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_REFERER, va("ioQ3://%s", NET_AdrToString(clc.serverAddress))); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_USERAGENT, va("%s %s", Q3_VERSION, qcurl_version())); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEFUNCTION, CL_cURL_CallbackWrite); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, &clc.download); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_NOPROGRESS, 0); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSFUNCTION, CL_cURL_CallbackProgress); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSDATA, NULL); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FAILONERROR, 1); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FOLLOWLOCATION, 1); qcurl_easy_setopt(clc.downloadCURL, CURLOPT_MAXREDIRS, 5); clc.downloadCURLM = qcurl_multi_init(); if(!clc.downloadCURLM) { qcurl_easy_cleanup(clc.downloadCURL); clc.downloadCURL = NULL; Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_multi_init() " "failed\n"); return; } qcurl_multi_add_handle(clc.downloadCURLM, clc.downloadCURL); if(!(clc.sv_allowDownload & DLF_NO_DISCONNECT) && !clc.cURLDisconnected) { CL_AddReliableCommand("disconnect"); CL_WritePacket(); CL_WritePacket(); CL_WritePacket(); clc.cURLDisconnected = qtrue; } }
/* =================== CL_GetServerCommand Set up argc/argv for the given command =================== */ qboolean CL_GetServerCommand( int serverCommandNumber ) { const char *s; char *cmd; static char bigConfigString[ BIG_INFO_STRING ]; int argc; // if we have irretrievably lost a reliable command, drop the connection if ( serverCommandNumber <= clc.serverCommandSequence - MAX_RELIABLE_COMMANDS ) { // when a demo record was started after the client got a whole bunch of // reliable commands then the client never got those first reliable commands if ( clc.demoplaying ) { return qfalse; } Com_Error( ERR_DROP, "CL_GetServerCommand: a reliable command was cycled out" ); } if ( serverCommandNumber > clc.serverCommandSequence ) { Com_Error( ERR_DROP, "CL_GetServerCommand: requested a command not received" ); } s = clc.serverCommands[ serverCommandNumber & ( MAX_RELIABLE_COMMANDS - 1 ) ]; clc.lastExecutedServerCommand = serverCommandNumber; if ( cl_showServerCommands->integer ) { // NERVE - SMF Com_Printf( "serverCommand: %i : %s\n", serverCommandNumber, s ); } rescan: Cmd_TokenizeString( s ); cmd = Cmd_Argv( 0 ); argc = Cmd_Argc(); if ( !strcmp( cmd, "disconnect" ) ) { // NERVE - SMF - allow server to indicate why they were disconnected if ( argc >= 2 ) { Com_Error( ERR_SERVERDISCONNECT, "Server Disconnected – %s", Cmd_Argv( 1 ) ); } else { Com_Error( ERR_SERVERDISCONNECT, "Server disconnected" ); } } if ( !strcmp( cmd, "bcs0" ) ) { Com_sprintf( bigConfigString, BIG_INFO_STRING, "cs %s %s", Cmd_Argv( 1 ), Cmd_QuoteString( Cmd_Argv( 2 ) ) ); return qfalse; } if ( !strcmp( cmd, "bcs1" ) ) { s = Cmd_QuoteString( Cmd_Argv( 2 ) ); if ( strlen( bigConfigString ) + strlen( s ) >= BIG_INFO_STRING ) { Com_Error( ERR_DROP, "bcs exceeded BIG_INFO_STRING" ); } strcat( bigConfigString, s ); return qfalse; } if ( !strcmp( cmd, "bcs2" ) ) { s = Cmd_QuoteString( Cmd_Argv( 2 ) ); if ( strlen( bigConfigString ) + strlen( s ) + 1 >= BIG_INFO_STRING ) { Com_Error( ERR_DROP, "bcs exceeded BIG_INFO_STRING" ); } strcat( bigConfigString, s ); strcat( bigConfigString, "\"" ); s = bigConfigString; goto rescan; } if ( !strcmp( cmd, "cs" ) ) { CL_ConfigstringModified(); // reparse the string, because CL_ConfigstringModified may have done another Cmd_TokenizeString() Cmd_TokenizeString( s ); return qtrue; } if ( !strcmp( cmd, "map_restart" ) ) { // clear notify lines and outgoing commands before passing // the restart to the cgame Con_ClearNotify(); memset( cl.cmds, 0, sizeof( cl.cmds ) ); return qtrue; } if ( !strcmp( cmd, "popup" ) ) { // direct server to client popup request, bypassing cgame // trap_UI_Popup(Cmd_Argv(1)); // if ( cls.state == CA_ACTIVE && !clc.demoplaying ) { // VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_CLIPBOARD); // Menus_OpenByName(Cmd_Argv(1)); // } return qfalse; } #ifdef USE_CRYPTO if ( cl_pubkeyID->integer && !strcmp( cmd, "pubkey_request" ) ) { char buffer[ MAX_STRING_CHARS ] = "pubkey "; mpz_get_str( buffer + 7, 16, public_key.n ); CL_AddReliableCommand( buffer ); return qfalse; } if ( cl_pubkeyID->integer && !strcmp( cmd, "pubkey_decrypt" ) ) { char buffer[ MAX_STRING_CHARS ] = "pubkey_identify "; unsigned int msg_len = MAX_STRING_CHARS - 16; mpz_t message; if ( argc == 1 ) { Com_Printf("%s", _( "^3Server sent a pubkey_decrypt command, but sent nothing to decrypt!\n" )); return qfalse; } mpz_init_set_str( message, Cmd_Argv( 1 ), 16 ); if ( rsa_decrypt( &private_key, &msg_len, ( unsigned char * ) buffer + 16, message ) ) { nettle_mpz_set_str_256_u( message, msg_len, ( unsigned char * ) buffer + 16 ); mpz_get_str( buffer + 16, 16, message ); CL_AddReliableCommand( buffer ); } mpz_clear( message ); return qfalse; } #endif // we may want to put a "connect to other server" command here // cgame can now act on the command return qtrue; }
/* ==================== CL_CgameSystemCalls The cgame module is making a system call ==================== */ intptr_t CL_CgameSystemCalls( intptr_t *args ) { switch ( args[ 0 ] ) { case CG_PRINT: Com_Printf( "%s", ( char * ) VMA( 1 ) ); return 0; case CG_ERROR: Com_Error( ERR_DROP, "%s", ( char * ) VMA( 1 ) ); case CG_MILLISECONDS: return Sys_Milliseconds(); case CG_CVAR_REGISTER: Cvar_Register( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[ 4 ] ); return 0; case CG_CVAR_UPDATE: Cvar_Update( VMA( 1 ) ); return 0; case CG_CVAR_SET: Cvar_Set( VMA( 1 ), VMA( 2 ) ); return 0; case CG_CVAR_VARIABLESTRINGBUFFER: VM_CheckBlock( args[2], args[3], "CVARVSB" ); Cvar_VariableStringBuffer( VMA( 1 ), VMA( 2 ), args[ 3 ] ); return 0; case CG_CVAR_LATCHEDVARIABLESTRINGBUFFER: VM_CheckBlock( args[2], args[3], "CVARLVSB" ); Cvar_LatchedVariableStringBuffer( VMA( 1 ), VMA( 2 ), args[ 3 ] ); return 0; case CG_ARGC: return Cmd_Argc(); case CG_ARGV: VM_CheckBlock( args[2], args[3], "ARGV" ); Cmd_ArgvBuffer( args[ 1 ], VMA( 2 ), args[ 3 ] ); return 0; case CG_ARGS: VM_CheckBlock( args[1], args[2], "ARGS" ); Cmd_ArgsBuffer( VMA( 1 ), args[ 2 ] ); return 0; case CG_LITERAL_ARGS: // FIXME VM_CheckBlock( args[1], args[2], "LARGS" ); Cmd_LiteralArgsBuffer( VMA( 1 ), args[ 2 ] ); // Cmd_ArgsBuffer(VMA(1), args[2]); return 0; case CG_GETDEMOSTATE: return CL_DemoState(); case CG_GETDEMOPOS: return CL_DemoPos(); case CG_FS_FOPENFILE: return FS_FOpenFileByMode( VMA( 1 ), VMA( 2 ), args[ 3 ] ); case CG_FS_READ: VM_CheckBlock( args[1], args[2], "FSREAD" ); FS_Read2( VMA( 1 ), args[ 2 ], args[ 3 ] ); return 0; case CG_FS_WRITE: VM_CheckBlock( args[1], args[2], "FSWRITE" ); return FS_Write( VMA( 1 ), args[ 2 ], args[ 3 ] ); case CG_FS_FCLOSEFILE: FS_FCloseFile( args[ 1 ] ); return 0; case CG_FS_GETFILELIST: VM_CheckBlock( args[3], args[4], "FSGFL" ); return FS_GetFileList( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[ 4 ] ); case CG_FS_DELETEFILE: return FS_Delete( VMA( 1 ) ); case CG_SENDCONSOLECOMMAND: Cbuf_AddText( VMA( 1 ) ); return 0; case CG_ADDCOMMAND: CL_AddCgameCommand( VMA( 1 ) ); return 0; case CG_REMOVECOMMAND: Cmd_RemoveCommand( VMA( 1 ) ); return 0; case CG_COMPLETE_CALLBACK: if ( completer ) { completer( VMA( 1 ) ); } return 0; case CG_SENDCLIENTCOMMAND: CL_AddReliableCommand( VMA( 1 ) ); return 0; case CG_UPDATESCREEN: SCR_UpdateScreen(); return 0; case CG_CM_LOADMAP: CL_CM_LoadMap( VMA( 1 ) ); return 0; case CG_CM_NUMINLINEMODELS: return CM_NumInlineModels(); case CG_CM_INLINEMODEL: return CM_InlineModel( args[ 1 ] ); case CG_CM_TEMPBOXMODEL: return CM_TempBoxModel( VMA( 1 ), VMA( 2 ), qfalse ); case CG_CM_TEMPCAPSULEMODEL: return CM_TempBoxModel( VMA( 1 ), VMA( 2 ), qtrue ); case CG_CM_POINTCONTENTS: return CM_PointContents( VMA( 1 ), args[ 2 ] ); case CG_CM_TRANSFORMEDPOINTCONTENTS: return CM_TransformedPointContents( VMA( 1 ), args[ 2 ], VMA( 3 ), VMA( 4 ) ); case CG_CM_BOXTRACE: CM_BoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[ 6 ], args[ 7 ], TT_AABB ); return 0; case CG_CM_TRANSFORMEDBOXTRACE: CM_TransformedBoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[ 6 ], args[ 7 ], VMA( 8 ), VMA( 9 ), TT_AABB ); return 0; case CG_CM_CAPSULETRACE: CM_BoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[ 6 ], args[ 7 ], TT_CAPSULE ); return 0; case CG_CM_TRANSFORMEDCAPSULETRACE: CM_TransformedBoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[ 6 ], args[ 7 ], VMA( 8 ), VMA( 9 ), TT_CAPSULE ); return 0; case CG_CM_BISPHERETRACE: CM_BiSphereTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMF( 4 ), VMF( 5 ), args[ 6 ], args[ 7 ] ); return 0; case CG_CM_TRANSFORMEDBISPHERETRACE: CM_TransformedBiSphereTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMF( 4 ), VMF( 5 ), args[ 6 ], args[ 7 ], VMA( 8 ) ); return 0; case CG_CM_MARKFRAGMENTS: return re.MarkFragments( args[ 1 ], VMA( 2 ), VMA( 3 ), args[ 4 ], VMA( 5 ), args[ 6 ], VMA( 7 ) ); case CG_R_PROJECTDECAL: re.ProjectDecal( args[ 1 ], args[ 2 ], VMA( 3 ), VMA( 4 ), VMA( 5 ), args[ 6 ], args[ 7 ] ); return 0; case CG_R_CLEARDECALS: re.ClearDecals(); return 0; case CG_S_STARTSOUND: S_StartSound( VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ] ); return 0; case CG_S_STARTSOUNDEX: S_StartSoundEx( VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ] ); return 0; case CG_S_STARTLOCALSOUND: S_StartLocalSound( args[ 1 ], args[ 2 ] ); return 0; case CG_S_CLEARLOOPINGSOUNDS: S_ClearLoopingSounds( args[ 1 ] ); return 0; case CG_S_CLEARSOUNDS: /*if(args[1] == 0) { S_ClearSounds(qtrue, qfalse); } else if(args[1] == 1) { S_ClearSounds(qtrue, qtrue); }*/ return 0; case CG_S_ADDLOOPINGSOUND: S_AddLoopingSound( args[ 1 ], VMA( 2 ), VMA( 3 ), args[ 4 ] ); return 0; case CG_S_ADDREALLOOPINGSOUND: S_AddRealLoopingSound( args[ 1 ], VMA( 2 ), VMA( 3 ), args[ 4 ] ); return 0; case CG_S_STOPLOOPINGSOUND: S_StopLoopingSound( args[ 1 ] ); return 0; case CG_S_STOPSTREAMINGSOUND: // FIXME //S_StopEntStreamingSound(args[1]); return 0; case CG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition( args[ 1 ], VMA( 2 ) ); return 0; case CG_S_GETVOICEAMPLITUDE: return S_GetVoiceAmplitude( args[ 1 ] ); case CG_S_GETSOUNDLENGTH: return S_GetSoundLength( args[ 1 ] ); // ydnar: for looped sound starts case CG_S_GETCURRENTSOUNDTIME: return S_GetCurrentSoundTime(); case CG_S_RESPATIALIZE: S_Respatialize( args[ 1 ], VMA( 2 ), VMA( 3 ), args[ 4 ] ); return 0; case CG_S_REGISTERSOUND: #ifdef DOOMSOUND ///// (SA) DOOMSOUND return S_RegisterSound( VMA( 1 ) ); #else return S_RegisterSound( VMA( 1 ), args[ 2 ] ); #endif ///// (SA) DOOMSOUND case CG_S_STARTBACKGROUNDTRACK: //S_StartBackgroundTrack(VMA(1), VMA(2), args[3]); //----(SA) added fadeup time S_StartBackgroundTrack( VMA( 1 ), VMA( 2 ) ); return 0; case CG_S_FADESTREAMINGSOUND: // FIXME //S_FadeStreamingSound(VMF(1), args[2], args[3]); //----(SA) added music/all-streaming options return 0; case CG_S_STARTSTREAMINGSOUND: // FIXME //return S_StartStreamingSound(VMA(1), VMA(2), args[3], args[4], args[5]); return 0; case CG_R_LOADWORLDMAP: re.LoadWorld( VMA( 1 ) ); return 0; case CG_R_REGISTERMODEL: #ifdef IPHONE GLimp_AcquireGL(); return re.RegisterModel( VMA( 1 ) ); GLimp_ReleaseGL(); #else return re.RegisterModel( VMA( 1 ) ); #endif // IPHONE case CG_R_REGISTERSKIN: return re.RegisterSkin( VMA( 1 ) ); //----(SA) added case CG_R_GETSKINMODEL: return re.GetSkinModel( args[ 1 ], VMA( 2 ), VMA( 3 ) ); case CG_R_GETMODELSHADER: return re.GetShaderFromModel( args[ 1 ], args[ 2 ], args[ 3 ] ); //----(SA) end case CG_R_REGISTERSHADER: #ifdef IPHONE_NOTYET GLimp_AcquireGL(); return re.RegisterShader( VMA( 1 ) ); GLimp_ReleaseGL(); #else return re.RegisterShader( VMA( 1 ) ); #endif // IPHONE case CG_R_REGISTERFONT: re.RegisterFontVM( VMA( 1 ), VMA( 2 ), args[ 3 ], VMA( 4 ) ); return 0; case CG_R_REGISTERSHADERNOMIP: #ifdef IPHONE_NOTYET GLimp_AcquireGL(); return re.RegisterShaderNoMip( VMA( 1 ) ); GLimp_ReleaseGL(); #else return re.RegisterShaderNoMip( VMA( 1 ) ); #endif // IPHONE #if defined( USE_REFLIGHT ) case CG_R_REGISTERSHADERLIGHTATTENUATION: return re.RegisterShaderLightAttenuation( VMA( 1 ) ); #endif case CG_R_CLEARSCENE: re.ClearScene(); return 0; case CG_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene( VMA( 1 ) ); return 0; #if defined( USE_REFLIGHT ) case CG_R_ADDREFLIGHTSTOSCENE: re.AddRefLightToScene( VMA( 1 ) ); return 0; #endif case CG_R_ADDPOLYTOSCENE: re.AddPolyToScene( args[ 1 ], args[ 2 ], VMA( 3 ) ); return 0; case CG_R_ADDPOLYSTOSCENE: re.AddPolysToScene( args[ 1 ], args[ 2 ], VMA( 3 ), args[ 4 ] ); return 0; case CG_R_ADDPOLYBUFFERTOSCENE: re.AddPolyBufferToScene( VMA( 1 ) ); return 0; case CG_R_ADDLIGHTTOSCENE: re.AddLightToScene( VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), args[ 7 ], args[ 8 ] ); return 0; case CG_R_ADDADDITIVELIGHTTOSCENE: re.AddAdditiveLightToScene( VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ) ); return 0; case CG_FS_SEEK: return FS_Seek( args[ 1 ], args[ 2 ], args[ 3 ] ); case CG_R_ADDCORONATOSCENE: re.AddCoronaToScene( VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[ 6 ], args[ 7 ] ); return 0; case CG_R_SETFOG: re.SetFog( args[ 1 ], args[ 2 ], args[ 3 ], VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ) ); return 0; case CG_R_SETGLOBALFOG: re.SetGlobalFog( args[ 1 ], args[ 2 ], VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ) ); return 0; case CG_R_RENDERSCENE: re.RenderScene( VMA( 1 ) ); return 0; case CG_R_SAVEVIEWPARMS: re.SaveViewParms(); return 0; case CG_R_RESTOREVIEWPARMS: re.RestoreViewParms(); return 0; case CG_R_SETCOLOR: re.SetColor( VMA( 1 ) ); return 0; // Tremulous case CG_R_SETCLIPREGION: re.SetClipRegion( VMA( 1 ) ); return 0; case CG_R_DRAWSTRETCHPIC: re.DrawStretchPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[ 9 ] ); return 0; case CG_R_DRAWROTATEDPIC: re.DrawRotatedPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[ 9 ], VMF( 10 ) ); return 0; case CG_R_DRAWSTRETCHPIC_GRADIENT: re.DrawStretchPicGradient( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[ 9 ], VMA( 10 ), args[ 11 ] ); return 0; case CG_R_DRAW2DPOLYS: re.Add2dPolys( VMA( 1 ), args[ 2 ], args[ 3 ] ); return 0; case CG_R_MODELBOUNDS: re.ModelBounds( args[ 1 ], VMA( 2 ), VMA( 3 ) ); return 0; case CG_R_LERPTAG: return re.LerpTag( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[ 4 ] ); case CG_GETGLCONFIG: CL_GetGlconfig( VMA( 1 ) ); return 0; case CG_GETGAMESTATE: CL_GetGameState( VMA( 1 ) ); return 0; case CG_GETCURRENTSNAPSHOTNUMBER: CL_GetCurrentSnapshotNumber( VMA( 1 ), VMA( 2 ) ); return 0; case CG_GETSNAPSHOT: return CL_GetSnapshot( args[ 1 ], VMA( 2 ) ); case CG_GETSERVERCOMMAND: return CL_GetServerCommand( args[ 1 ] ); case CG_GETCURRENTCMDNUMBER: return CL_GetCurrentCmdNumber(); case CG_GETUSERCMD: return CL_GetUserCmd( args[ 1 ], VMA( 2 ) ); case CG_SETUSERCMDVALUE: CL_SetUserCmdValue( args[ 1 ], args[ 2 ], VMF( 3 ), args[ 4 ] ); return 0; case CG_SETCLIENTLERPORIGIN: CL_SetClientLerpOrigin( VMF( 1 ), VMF( 2 ), VMF( 3 ) ); return 0; case CG_MEMORY_REMAINING: return Hunk_MemoryRemaining(); case CG_KEY_ISDOWN: return Key_IsDown( args[ 1 ] ); case CG_KEY_GETCATCHER: return Key_GetCatcher(); case CG_KEY_SETCATCHER: Key_SetCatcher( args[ 1 ] ); return 0; case CG_KEY_GETKEY: return Key_GetKey( VMA( 1 ) ); case CG_KEY_GETOVERSTRIKEMODE: return Key_GetOverstrikeMode(); case CG_KEY_SETOVERSTRIKEMODE: Key_SetOverstrikeMode( args[ 1 ] ); return 0; case CG_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case CG_REAL_TIME: return Com_RealTime( VMA( 1 ) ); case CG_SNAPVECTOR: Q_SnapVector( VMA( 1 ) ); return 0; case CG_CIN_PLAYCINEMATIC: return CIN_PlayCinematic( VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ], args[ 6 ] ); case CG_CIN_STOPCINEMATIC: return CIN_StopCinematic( args[ 1 ] ); case CG_CIN_RUNCINEMATIC: return CIN_RunCinematic( args[ 1 ] ); case CG_CIN_DRAWCINEMATIC: CIN_DrawCinematic( args[ 1 ] ); return 0; case CG_CIN_SETEXTENTS: CIN_SetExtents( args[ 1 ], args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ] ); return 0; case CG_R_REMAP_SHADER: re.RemapShader( VMA( 1 ), VMA( 2 ), VMA( 3 ) ); return 0; case CG_LOADCAMERA: //return loadCamera(args[1], VMA(2)); return 0; case CG_STARTCAMERA: //if(args[1] == 0) //{ // CAM_PRIMARY // cl.cameraMode = qtrue; //} //startCamera(args[1], args[2]); return 0; case CG_STOPCAMERA: //if(args[1] == 0) //{ // CAM_PRIMARY // cl.cameraMode = qfalse; //} return 0; case CG_GETCAMERAINFO: //return getCameraInfo(args[1], args[2], VMA(3), VMA(4), VMA(5)); return 0; case CG_GET_ENTITY_TOKEN: VM_CheckBlock( args[1], args[2], "GETET" ); return re.GetEntityToken( VMA( 1 ), args[ 2 ] ); case CG_INGAME_POPUP: if ( cls.state == CA_ACTIVE && !clc.demoplaying ) { if ( uivm ) { // Gordon: can be called as the system is shutting down VM_Call( uivm, UI_SET_ACTIVE_MENU, args[ 1 ] ); } } return 0; case CG_INGAME_CLOSEPOPUP: return 0; case CG_KEY_GETBINDINGBUF: VM_CheckBlock( args[2], args[3], "KEYGBB" ); Key_GetBindingBuf( args[ 1 ], VMA( 2 ), args[ 3 ] ); return 0; case CG_KEY_SETBINDING: Key_SetBinding( args[ 1 ], VMA( 2 ) ); return 0; case CG_PARSE_ADD_GLOBAL_DEFINE: return Parse_AddGlobalDefine( VMA( 1 ) ); case CG_PARSE_LOAD_SOURCE: return Parse_LoadSourceHandle( VMA( 1 ) ); case CG_PARSE_FREE_SOURCE: return Parse_FreeSourceHandle( args[ 1 ] ); case CG_PARSE_READ_TOKEN: return Parse_ReadTokenHandle( args[ 1 ], VMA( 2 ) ); case CG_PARSE_SOURCE_FILE_AND_LINE: return Parse_SourceFileAndLine( args[ 1 ], VMA( 2 ), VMA( 3 ) ); case CG_KEY_KEYNUMTOSTRINGBUF: VM_CheckBlock( args[2], args[3], "KEYNTSB" ); Key_KeynumToStringBuf( args[ 1 ], VMA( 2 ), args[ 3 ] ); return 0; case CG_KEY_BINDINGTOKEYS: Key_GetBindingByString( VMA( 1 ), VMA( 2 ), VMA( 3 ) ); return 0; case CG_S_FADEALLSOUNDS: // FIXME //S_FadeAllSounds(VMF(1), args[2], args[3]); return 0; case CG_R_INPVS: return re.inPVS( VMA( 1 ), VMA( 2 ) ); case CG_GETHUNKDATA: Com_GetHunkInfo( VMA( 1 ), VMA( 2 ) ); return 0; case CG_PUMPEVENTLOOP: // Com_EventLoop(); // CL_WritePacket(); return 0; //zinx - binary channel case CG_SENDMESSAGE: VM_CheckBlock( args[1], args[2], "SENDM" ); CL_SendBinaryMessage( VMA( 1 ), args[ 2 ] ); return 0; case CG_MESSAGESTATUS: return CL_BinaryMessageStatus(); //bani - dynamic shaders case CG_R_LOADDYNAMICSHADER: return re.LoadDynamicShader( VMA( 1 ), VMA( 2 ) ); // fretn - render to texture case CG_R_RENDERTOTEXTURE: re.RenderToTexture( args[ 1 ], args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ] ); return 0; //bani case CG_R_GETTEXTUREID: return re.GetTextureId( VMA( 1 ) ); //bani - flush gl rendering buffers case CG_R_FINISH: re.Finish(); return 0; case CG_GETDEMONAME: VM_CheckBlock( args[1], args[2], "GETDM" ); CL_DemoName( VMA( 1 ), args[ 2 ] ); return 0; case CG_R_LIGHTFORPOINT: return re.LightForPoint( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ) ); case CG_S_SOUNDDURATION: return S_SoundDuration( args[ 1 ] ); #if defined( USE_REFENTITY_ANIMATIONSYSTEM ) case CG_R_REGISTERANIMATION: return re.RegisterAnimation( VMA( 1 ) ); case CG_R_CHECKSKELETON: return re.CheckSkeleton( VMA( 1 ), args[ 2 ], args[ 3 ] ); case CG_R_BUILDSKELETON: return re.BuildSkeleton( VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ], VMF( 5 ), args[ 6 ] ); case CG_R_BLENDSKELETON: return re.BlendSkeleton( VMA( 1 ), VMA( 2 ), VMF( 3 ) ); case CG_R_BONEINDEX: return re.BoneIndex( args[ 1 ], VMA( 2 ) ); case CG_R_ANIMNUMFRAMES: return re.AnimNumFrames( args[ 1 ] ); case CG_R_ANIMFRAMERATE: return re.AnimFrameRate( args[ 1 ] ); #endif case CG_REGISTER_BUTTON_COMMANDS: CL_RegisterButtonCommands( VMA( 1 ) ); return 0; case CG_GETCLIPBOARDDATA: VM_CheckBlock( args[1], args[2], "GETCLIP" ); if ( cl_allowPaste->integer ) { CL_GetClipboardData( VMA(1), args[2], args[3] ); } else { ( (char *) VMA( 1 ) )[0] = '\0'; } return 0; case CG_QUOTESTRING: Cmd_QuoteStringBuffer( VMA( 1 ), VMA( 2 ), args[ 3 ] ); return 0; case CG_GETTEXT: strncpy( VMA(1), __(VMA(2)), args[3] ); return 0; case CG_R_GLYPH: re.GlyphVM( args[1], VMA(2), VMA(3) ); return 0; case CG_R_GLYPHCHAR: re.GlyphCharVM( args[1], args[2], VMA(3) ); return 0; case CG_R_UREGISTERFONT: re.UnregisterFontVM( args[1] ); return 0; default: Com_Error( ERR_DROP, "Bad cgame system trap: %ld", ( long int ) args[ 0 ] ); } return 0; }
/* * CL_ParseServerData */ static void CL_ParseServerData( msg_t *msg ) { const char *str, *gamedir; int i, sv_bitflags, numpure; int http_portnum; Com_DPrintf( "Serverdata packet received.\n" ); // wipe the client_state_t struct CL_ClearState(); CL_SetClientState( CA_CONNECTED ); // parse protocol version number i = MSG_ReadLong( msg ); if( i != APP_PROTOCOL_VERSION ) Com_Error( ERR_DROP, "Server returned version %i, not %i", i, APP_PROTOCOL_VERSION ); cl.servercount = MSG_ReadLong( msg ); cl.snapFrameTime = (unsigned int)MSG_ReadShort( msg ); // set extrapolation time to half snapshot time Cvar_ForceSet( "cl_extrapolationTime", va( "%i", (unsigned int)( cl.snapFrameTime * 0.5 ) ) ); cl_extrapolationTime->modified = qfalse; // base game directory str = MSG_ReadString( msg ); if( !str || !str[0] ) Com_Error( ERR_DROP, "Server sent an empty base game directory" ); if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) ) Com_Error( ERR_DROP, "Server sent an invalid base game directory: %s", str ); if( strcmp( FS_BaseGameDirectory(), str ) ) { Com_Error( ERR_DROP, "Server has different base game directory (%s) than the client (%s)", str, FS_BaseGameDirectory() ); } // game directory str = MSG_ReadString( msg ); if( !str || !str[0] ) Com_Error( ERR_DROP, "Server sent an empty game directory" ); if( !COM_ValidateRelativeFilename( str ) || strchr( str, '/' ) ) Com_Error( ERR_DROP, "Server sent an invalid game directory: %s", str ); gamedir = FS_GameDirectory(); if( strcmp( str, gamedir ) ) { // shutdown the cgame module first in case it is running for whatever reason // (happens on wswtv in lobby), otherwise precaches that are going to follow // will probably f**k up (like models trying to load before the world model) CL_GameModule_Shutdown(); if( !FS_SetGameDirectory( str, qtrue ) ) Com_Error( ERR_DROP, "Failed to load game directory set by server: %s", str ); ML_Restart( qtrue ); } // parse player entity number cl.playernum = MSG_ReadShort( msg ); // get the full level name Q_strncpyz( cl.servermessage, MSG_ReadString( msg ), sizeof( cl.servermessage ) ); sv_bitflags = MSG_ReadByte( msg ); if( cls.demo.playing ) { cls.reliable = ( sv_bitflags & SV_BITFLAGS_RELIABLE ); } else { if( cls.reliable != ( ( sv_bitflags & SV_BITFLAGS_RELIABLE ) != 0 ) ) Com_Error( ERR_DROP, "Server and client disagree about connection reliability" ); } // builting HTTP server port if( cls.httpbaseurl ) { Mem_Free( cls.httpbaseurl ); cls.httpbaseurl = NULL; } if( ( sv_bitflags & SV_BITFLAGS_HTTP ) != 0 ) { if( ( sv_bitflags & SV_BITFLAGS_HTTP_BASEURL ) != 0 ) { // read base upstream url cls.httpbaseurl = ZoneCopyString( MSG_ReadString( msg ) ); } else { http_portnum = MSG_ReadShort( msg ) & 0xffff; cls.httpaddress = cls.serveraddress; if( cls.httpaddress.type == NA_IP6 ) { cls.httpaddress.address.ipv6.port = BigShort( http_portnum ); } else { cls.httpaddress.address.ipv4.port = BigShort( http_portnum ); } if( http_portnum ) { if( cls.httpaddress.type == NA_LOOPBACK ) { cls.httpbaseurl = ZoneCopyString( va( "http://localhost:%hu/", http_portnum ) ); } else { cls.httpbaseurl = ZoneCopyString( va( "http://%s/", NET_AddressToString( &cls.httpaddress ) ) ); } } } } // pure list // clean old, if necessary Com_FreePureList( &cls.purelist ); // add new numpure = MSG_ReadShort( msg ); while( numpure > 0 ) { const char *pakname = MSG_ReadString( msg ); const unsigned checksum = MSG_ReadLong( msg ); Com_AddPakToPureList( &cls.purelist, pakname, checksum, NULL ); numpure--; } //assert( numpure == 0 ); // get the configstrings request CL_AddReliableCommand( va( "configstrings %i 0", cl.servercount ) ); cls.sv_pure = ( sv_bitflags & SV_BITFLAGS_PURE ) != 0; cls.sv_tv = ( sv_bitflags & SV_BITFLAGS_TVSERVER ) != 0; #ifdef PURE_CHEAT cls.sv_pure = qfalse; #endif // separate the printfs so the server message can have a color Com_Printf( S_COLOR_WHITE "\n" "=====================================\n" ); Com_Printf( S_COLOR_WHITE "%s\n\n", cl.servermessage ); }
/* ===================== CL_ParseDownload A download message has been received from the server ===================== */ void CL_ParseDownload ( msg_t *msg ) { int size; unsigned char data[MAX_MSGLEN]; uint16_t block; if (!*clc.downloadTempName) { Com_Printf("Server sending download, but no download was requested\n"); CL_AddReliableCommand("stopdl", qfalse); return; } // read the data block = MSG_ReadShort ( msg ); if(!block && !clc.downloadBlock) { // block zero is special, contains file size clc.downloadSize = MSG_ReadLong ( msg ); Cvar_SetValue( "cl_downloadSize", clc.downloadSize ); if (clc.downloadSize < 0) { Com_Error( ERR_DROP, "%s", MSG_ReadString( msg ) ); return; } } size = MSG_ReadShort ( msg ); if (size < 0 || size > sizeof(data)) { Com_Error(ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk", size); return; } MSG_ReadData(msg, data, size); if((clc.downloadBlock & 0xFFFF) != block) { Com_DPrintf( "CL_ParseDownload: Expected block %d, got %d\n", (clc.downloadBlock & 0xFFFF), block); return; } // open the file if not opened yet if (!clc.download) { clc.download = FS_SV_FOpenFileWrite( clc.downloadTempName ); if (!clc.download) { Com_Printf( "Could not create %s\n", clc.downloadTempName ); CL_AddReliableCommand("stopdl", qfalse); CL_NextDownload(); return; } } if (size) FS_Write( data, size, clc.download ); CL_AddReliableCommand(va("nextdl %d", clc.downloadBlock), qfalse); clc.downloadBlock++; clc.downloadCount += size; // So UI gets access to it Cvar_SetValue( "cl_downloadCount", clc.downloadCount ); if (!size) { // A zero length block means EOF if (clc.download) { FS_FCloseFile( clc.download ); clc.download = 0; // rename the file FS_SV_Rename ( clc.downloadTempName, clc.downloadName, qfalse ); } // send intentions now // We need this because without it, we would hold the last nextdl and then start // loading right away. If we take a while to load, the server is happily trying // to send us that last block over and over. // Write it twice to help make sure we acknowledge the download CL_WritePacket(); CL_WritePacket(); // get another file if needed CL_NextDownload (); } }
// The cgame module is making a system call qintptr CLWS_CgameSystemCalls( qintptr* args ) { switch ( args[ 0 ] ) { case WSCG_PRINT: common->Printf( "%s", ( char* )VMA( 1 ) ); return 0; case WSCG_ERROR: common->Error( "%s", ( char* )VMA( 1 ) ); return 0; case WSCG_MILLISECONDS: return Sys_Milliseconds(); case WSCG_CVAR_REGISTER: Cvar_Register( ( vmCvar_t* )VMA( 1 ), ( char* )VMA( 2 ), ( char* )VMA( 3 ), args[ 4 ] ); return 0; case WSCG_CVAR_UPDATE: Cvar_Update( ( vmCvar_t* )VMA( 1 ) ); return 0; case WSCG_CVAR_SET: Cvar_Set( ( char* )VMA( 1 ), ( char* )VMA( 2 ) ); return 0; case WSCG_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] ); return 0; case WSCG_ARGC: return Cmd_Argc(); case WSCG_ARGV: Cmd_ArgvBuffer( args[ 1 ], ( char* )VMA( 2 ), args[ 3 ] ); return 0; case WSCG_ARGS: Cmd_ArgsBuffer( ( char* )VMA( 1 ), args[ 2 ] ); return 0; case WSCG_FS_FOPENFILE: return FS_FOpenFileByMode( ( char* )VMA( 1 ), ( fileHandle_t* )VMA( 2 ), ( fsMode_t )args[ 3 ] ); case WSCG_FS_READ: FS_Read( VMA( 1 ), args[ 2 ], args[ 3 ] ); return 0; case WSCG_FS_WRITE: return FS_Write( VMA( 1 ), args[ 2 ], args[ 3 ] ); case WSCG_FS_FCLOSEFILE: FS_FCloseFile( args[ 1 ] ); return 0; case WSCG_SENDCONSOLECOMMAND: Cbuf_AddText( ( char* )VMA( 1 ) ); return 0; case WSCG_ADDCOMMAND: CLT3_AddCgameCommand( ( char* )VMA( 1 ) ); return 0; case WSCG_REMOVECOMMAND: Cmd_RemoveCommand( ( char* )VMA( 1 ) ); return 0; case WSCG_SENDCLIENTCOMMAND: CL_AddReliableCommand( ( char* )VMA( 1 ) ); return 0; case WSCG_UPDATESCREEN: SCR_UpdateScreen(); return 0; case WSCG_CM_LOADMAP: CLT3_CM_LoadMap( ( char* )VMA( 1 ) ); return 0; case WSCG_CM_NUMINLINEMODELS: return CM_NumInlineModels(); case WSCG_CM_INLINEMODEL: return CM_InlineModel( args[ 1 ] ); case WSCG_CM_TEMPBOXMODEL: return CM_TempBoxModel( ( float* )VMA( 1 ), ( float* )VMA( 2 ), false ); case WSCG_CM_TEMPCAPSULEMODEL: return CM_TempBoxModel( ( float* )VMA( 1 ), ( float* )VMA( 2 ), true ); case WSCG_CM_POINTCONTENTS: return CM_PointContentsQ3( ( float* )VMA( 1 ), args[ 2 ] ); case WSCG_CM_TRANSFORMEDPOINTCONTENTS: return CM_TransformedPointContentsQ3( ( float* )VMA( 1 ), args[ 2 ], ( float* )VMA( 3 ), ( float* )VMA( 4 ) ); case WSCG_CM_BOXTRACE: CM_BoxTraceQ3( ( q3trace_t* )VMA( 1 ), ( float* )VMA( 2 ), ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ), args[ 6 ], args[ 7 ], false ); return 0; case WSCG_CM_TRANSFORMEDBOXTRACE: CM_TransformedBoxTraceQ3( ( q3trace_t* )VMA( 1 ), ( float* )VMA( 2 ), ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ), args[ 6 ], args[ 7 ], ( float* )VMA( 8 ), ( float* )VMA( 9 ), false ); return 0; case WSCG_CM_CAPSULETRACE: CM_BoxTraceQ3( ( q3trace_t* )VMA( 1 ), ( float* )VMA( 2 ), ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ), args[ 6 ], args[ 7 ], true ); return 0; case WSCG_CM_TRANSFORMEDCAPSULETRACE: CM_TransformedBoxTraceQ3( ( q3trace_t* )VMA( 1 ), ( float* )VMA( 2 ), ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ), args[ 6 ], args[ 7 ], ( float* )VMA( 8 ), ( float* )VMA( 9 ), true ); return 0; case WSCG_CM_MARKFRAGMENTS: return R_MarkFragmentsWolf( args[ 1 ], ( const vec3_t* )VMA( 2 ), ( float* )VMA( 3 ), args[ 4 ], ( float* )VMA( 5 ), args[ 6 ], ( markFragment_t* )VMA( 7 ) ); case WSCG_S_STARTSOUND: S_StartSound( ( float* )VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ], 0.5 ); return 0; case WSCG_S_STARTSOUNDEX: S_StartSoundEx( ( float* )VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ], 127 ); return 0; case WSCG_S_STARTLOCALSOUND: S_StartLocalSound( args[ 1 ], args[ 2 ], 127 ); return 0; case WSCG_S_CLEARLOOPINGSOUNDS: CLWS_ClearLoopingSounds( args[ 1 ] ); return 0; case WSCG_S_ADDLOOPINGSOUND: // FIXME MrE: handling of looping sounds changed S_AddLoopingSound( args[ 1 ], ( float* )VMA( 2 ), ( float* )VMA( 3 ), args[ 4 ], args[ 5 ], args[ 6 ], 0 ); return 0; case WSCG_S_STOPSTREAMINGSOUND: S_StopEntStreamingSound( args[ 1 ] ); return 0; case WSCG_S_STOPLOOPINGSOUND: // RF, not functional anymore, since we reverted to old looping code return 0; case WSCG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition( args[ 1 ], ( float* )VMA( 2 ) ); return 0; case WSCG_S_GETVOICEAMPLITUDE: return S_GetVoiceAmplitude( args[ 1 ] ); case WSCG_S_RESPATIALIZE: S_Respatialize( args[ 1 ], ( float* )VMA( 2 ), ( vec3_t* )VMA( 3 ), args[ 4 ] ); return 0; case WSCG_S_REGISTERSOUND: return S_RegisterSound( ( char* )VMA( 1 ) ); case WSCG_S_STARTBACKGROUNDTRACK: S_StartBackgroundTrack( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] ); //----(SA) added fadeup time return 0; case WSCG_S_FADESTREAMINGSOUND: S_FadeStreamingSound( VMF( 1 ), args[ 2 ], args[ 3 ] ); //----(SA) added music/all-streaming options return 0; case WSCG_S_STARTSTREAMINGSOUND: S_StartStreamingSound( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ], args[ 4 ], args[ 5 ] ); return 0; case WSCG_S_FADEALLSOUNDS: S_FadeAllSounds( VMF( 1 ), args[ 2 ], false ); //----(SA) added return 0; case WSCG_R_LOADWORLDMAP: R_LoadWorld( ( char* )VMA( 1 ) ); return 0; case WSCG_R_REGISTERMODEL: return R_RegisterModel( ( char* )VMA( 1 ) ); case WSCG_R_REGISTERSKIN: return R_RegisterSkin( ( char* )VMA( 1 ) ); case WSCG_R_GETSKINMODEL: return R_GetSkinModel( args[ 1 ], ( char* )VMA( 2 ), ( char* )VMA( 3 ) ); case WSCG_R_GETMODELSHADER: return R_GetShaderFromModel( args[ 1 ], args[ 2 ], args[ 3 ] ); case WSCG_R_REGISTERSHADER: return R_RegisterShader( ( char* )VMA( 1 ) ); case WSCG_R_REGISTERFONT: R_RegisterFont( ( char* )VMA( 1 ), args[ 2 ], ( fontInfo_t* )VMA( 3 ) ); case WSCG_R_REGISTERSHADERNOMIP: return R_RegisterShaderNoMip( ( char* )VMA( 1 ) ); case WSCG_R_CLEARSCENE: R_ClearScene(); return 0; case WSCG_R_ADDREFENTITYTOSCENE: CLWS_AddRefEntityToScene( ( wsrefEntity_t* )VMA( 1 ) ); return 0; case WSCG_R_ADDPOLYTOSCENE: R_AddPolyToScene( args[ 1 ], args[ 2 ], ( polyVert_t* )VMA( 3 ), 1 ); return 0; case WSCG_R_ADDPOLYSTOSCENE: R_AddPolyToScene( args[ 1 ], args[ 2 ], ( polyVert_t* )VMA( 3 ), args[ 4 ] ); return 0; case WSCG_RB_ZOMBIEFXADDNEWHIT: return 0; case WSCG_R_ADDLIGHTTOSCENE: R_AddLightToScene( ( float* )VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[ 6 ] ); return 0; case WSCG_R_ADDCORONATOSCENE: R_AddCoronaToScene( ( float* )VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[ 6 ], args[ 7 ] ); return 0; case WSCG_R_SETFOG: R_SetFog( args[ 1 ], args[ 2 ], args[ 3 ], VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ) ); return 0; case WSCG_R_RENDERSCENE: CLWS_RenderScene( ( wsrefdef_t* )VMA( 1 ) ); return 0; case WSCG_R_SETCOLOR: R_SetColor( ( float* )VMA( 1 ) ); return 0; case WSCG_R_DRAWSTRETCHPIC: R_StretchPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[ 9 ] ); return 0; case WSCG_R_DRAWSTRETCHPIC_GRADIENT: R_StretchPicGradient( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[ 9 ], ( float* )VMA( 10 ), args[ 11 ] ); return 0; case WSCG_R_MODELBOUNDS: R_ModelBounds( args[ 1 ], ( float* )VMA( 2 ), ( float* )VMA( 3 ) ); return 0; case WSCG_R_LERPTAG: return CLWS_LerpTag( ( orientation_t* )VMA( 1 ), ( wsrefEntity_t* )VMA( 2 ), ( char* )VMA( 3 ), args[ 4 ] ); case WSCG_GETGLCONFIG: CLWS_GetGlconfig( ( wsglconfig_t* )VMA( 1 ) ); return 0; case WSCG_GETGAMESTATE: CLWS_GetGameState( ( wsgameState_t* )VMA( 1 ) ); return 0; case WSCG_GETCURRENTSNAPSHOTNUMBER: CLWS_GetCurrentSnapshotNumber( ( int* )VMA( 1 ), ( int* )VMA( 2 ) ); return 0; case WSCG_GETSNAPSHOT: return CLWS_GetSnapshot( args[ 1 ], ( wssnapshot_t* )VMA( 2 ) ); case WSCG_GETSERVERCOMMAND: return CLT3_GetServerCommand( args[ 1 ] ); case WSCG_GETCURRENTCMDNUMBER: return CLT3_GetCurrentCmdNumber(); case WSCG_GETUSERCMD: return CLWS_GetUserCmd( args[ 1 ], ( wsusercmd_t* )VMA( 2 ) ); case WSCG_SETUSERCMDVALUE: CLWS_SetUserCmdValue( args[ 1 ], args[ 2 ], VMF( 3 ), args[ 4 ] ); //----(SA) modified // NERVE - SMF - added fourth arg [cld] return 0; case WSCG_MEMORY_REMAINING: return 0x4000000; case WSCG_KEY_ISDOWN: return Key_IsDown( args[ 1 ] ); case WSCG_KEY_GETCATCHER: return Key_GetCatcher(); case WSCG_KEY_SETCATCHER: KeyQ3_SetCatcher( args[ 1 ] ); return 0; case WSCG_KEY_GETKEY: return Key_GetKey( ( char* )VMA( 1 ) ); case WSCG_MEMSET: return ( qintptr )memset( VMA( 1 ), args[ 2 ], args[ 3 ] ); case WSCG_MEMCPY: return ( qintptr )memcpy( VMA( 1 ), VMA( 2 ), args[ 3 ] ); case WSCG_STRNCPY: String::NCpy( ( char* )VMA( 1 ), ( char* )VMA( 2 ), args[ 3 ] ); return args[ 1 ]; case WSCG_SIN: return FloatAsInt( sin( VMF( 1 ) ) ); case WSCG_COS: return FloatAsInt( cos( VMF( 1 ) ) ); case WSCG_ATAN2: return FloatAsInt( atan2( VMF( 1 ), VMF( 2 ) ) ); case WSCG_SQRT: return FloatAsInt( sqrt( VMF( 1 ) ) ); case WSCG_FLOOR: return FloatAsInt( floor( VMF( 1 ) ) ); case WSCG_CEIL: return FloatAsInt( ceil( VMF( 1 ) ) ); case WSCG_ACOS: return FloatAsInt( idMath::ACos( VMF( 1 ) ) ); case WSCG_PC_ADD_GLOBAL_DEFINE: return PC_AddGlobalDefine( ( char* )VMA( 1 ) ); case WSCG_PC_LOAD_SOURCE: return PC_LoadSourceHandle( ( char* )VMA( 1 ) ); case WSCG_PC_FREE_SOURCE: return PC_FreeSourceHandle( args[ 1 ] ); case WSCG_PC_READ_TOKEN: return PC_ReadTokenHandleQ3( args[ 1 ], ( q3pc_token_t* )VMA( 2 ) ); case WSCG_PC_SOURCE_FILE_AND_LINE: return PC_SourceFileAndLine( args[ 1 ], ( char* )VMA( 2 ), ( int* )VMA( 3 ) ); case WSCG_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case WSCG_REAL_TIME: return Com_RealTime( ( qtime_t* )VMA( 1 ) ); case WSCG_SNAPVECTOR: Sys_SnapVector( ( float* )VMA( 1 ) ); return 0; case WSCG_SENDMOVESPEEDSTOGAME: SVWS_SendMoveSpeedsToGame( args[ 1 ], ( char* )VMA( 2 ) ); return 0; case WSCG_CIN_PLAYCINEMATIC: return CIN_PlayCinematicStretched( ( char* )VMA( 1 ), args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ], args[ 6 ] ); case WSCG_CIN_STOPCINEMATIC: return CIN_StopCinematic( args[ 1 ] ); case WSCG_CIN_RUNCINEMATIC: return CIN_RunCinematic( args[ 1 ] ); case WSCG_CIN_DRAWCINEMATIC: CIN_DrawCinematic( args[ 1 ] ); return 0; case WSCG_CIN_SETEXTENTS: CIN_SetExtents( args[ 1 ], args[ 2 ], args[ 3 ], args[ 4 ], args[ 5 ] ); return 0; case WSCG_R_REMAP_SHADER: R_RemapShader( ( char* )VMA( 1 ), ( char* )VMA( 2 ), ( char* )VMA( 3 ) ); return 0; case WSCG_TESTPRINTINT: common->Printf( "%s%i\n", ( char* )VMA( 1 ), static_cast<int>( args[ 2 ] ) ); return 0; case WSCG_TESTPRINTFLOAT: common->Printf( "%s%f\n", ( char* )VMA( 1 ), VMF( 2 ) ); return 0; case WSCG_LOADCAMERA: return loadCamera( args[ 1 ], ( char* )VMA( 2 ) ); case WSCG_STARTCAMERA: CLWS_StartCamera( args[ 1 ], args[ 2 ] ); return 0; case WSCG_STOPCAMERA: CLWS_StopCamera( args[ 1 ] ); return 0; case WSCG_GETCAMERAINFO: return getCameraInfo( args[ 1 ], args[ 2 ], ( float* )VMA( 3 ), ( float* )VMA( 4 ), ( float* )VMA( 5 ) ); case WSCG_GET_ENTITY_TOKEN: return R_GetEntityToken( ( char* )VMA( 1 ), args[ 2 ] ); case WSCG_INGAME_POPUP: CLWS_InGamePopup( ( char* )VMA( 1 ) ); return 0; case WSCG_INGAME_CLOSEPOPUP: UIT3_KeyEvent( K_ESCAPE, true ); return 0; case WSCG_LIMBOCHAT: CLT3_AddToLimboChat( ( char* )VMA( 1 ) ); return 0; case WSCG_GETMODELINFO: return SVWS_GetModelInfo( args[ 1 ], ( char* )VMA( 2 ), ( animModelInfo_t** )VMA( 3 ) ); default: common->Error( "Bad cgame system trap: %i", static_cast<int>( args[ 0 ] ) ); } return 0; }
static void CLQW_ParseServerData( QMsg& message ) { common->DPrintf( "Serverdata packet received.\n" ); Cbuf_Execute(); // make sure any stuffed commands are done R_Shutdown( false ); CL_InitRenderer(); // // wipe the clientActive_t struct // CL_ClearState(); // parse protocol version number // allow 2.2 and 2.29 demos to play int protover = message.ReadLong(); if ( protover != QWPROTOCOL_VERSION && !( clc.demoplaying && ( protover == 26 || protover == 27 || protover == 28 ) ) ) { common->Error( "Server returned version %i, not %i\nYou probably need to upgrade.\nCheck http://www.quakeworld.net/", protover, QWPROTOCOL_VERSION ); } cl.servercount = message.ReadLong(); // game directory const char* str = message.ReadString2(); bool cflag = false; if ( String::ICmp( fsqhw_gamedirfile, str ) ) { // save current config Com_WriteConfiguration(); cflag = true; } FS_SetGamedirQHW( str ); //ZOID--run the autoexec.cfg in the gamedir //if it exists if ( cflag ) { if ( FS_FileExists( "config.cfg" ) ) { Cbuf_AddText( "cl_warncmd 0\n" ); Cbuf_AddText( "exec config.cfg\n" ); Cbuf_AddText( "exec frontend.cfg\n" ); Cbuf_AddText( "cl_warncmd 1\n" ); } } // parse player slot, high bit means spectator cl.playernum = message.ReadByte(); if ( cl.playernum & 128 ) { cl.qh_spectator = true; cl.playernum &= ~128; } cl.viewentity = cl.playernum + 1; // get the full level name str = const_cast<char*>( message.ReadString2() ); String::NCpy( cl.qh_levelname, str, sizeof ( cl.qh_levelname ) - 1 ); // get the movevars movevars.gravity = message.ReadFloat(); movevars.stopspeed = message.ReadFloat(); movevars.maxspeed = message.ReadFloat(); movevars.spectatormaxspeed = message.ReadFloat(); movevars.accelerate = message.ReadFloat(); movevars.airaccelerate = message.ReadFloat(); movevars.wateraccelerate = message.ReadFloat(); movevars.friction = message.ReadFloat(); movevars.waterfriction = message.ReadFloat(); movevars.entgravity = message.ReadFloat(); // seperate the printfs so the server message can have a color common->Printf( "\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n" ); common->Printf( S_COLOR_ORANGE "%s" S_COLOR_WHITE "\n", str ); // ask for the sound list next Com_Memset( cl.qh_sound_name, 0, sizeof ( cl.qh_sound_name ) ); CL_AddReliableCommand( va( "soundlist %i %i", cl.servercount, 0 ) ); // now waiting for downloads, etc cls.state = CA_LOADING; }
intptr_t CL_CgameSystemCalls(intptr_t *args) { switch (args[0]) { case CG_PRINT: Com_Printf("%s", (char *)VMA(1)); return 0; case CG_ERROR: Com_Error(ERR_DROP, "%s", (char *)VMA(1)); return 0; case CG_MILLISECONDS: return Sys_Milliseconds(); case CG_CVAR_REGISTER: Cvar_Register(VMA(1), VMA(2), VMA(3), args[4]); return 0; case CG_CVAR_UPDATE: Cvar_Update(VMA(1)); return 0; case CG_CVAR_SET: Cvar_SetSafe(VMA(1), VMA(2)); return 0; case CG_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer(VMA(1), VMA(2), args[3]); return 0; case CG_CVAR_LATCHEDVARIABLESTRINGBUFFER: Cvar_LatchedVariableStringBuffer(VMA(1), VMA(2), args[3]); return 0; case CG_ARGC: return Cmd_Argc(); case CG_ARGV: Cmd_ArgvBuffer(args[1], VMA(2), args[3]); return 0; case CG_ARGS: Cmd_ArgsBuffer(VMA(1), args[2]); return 0; case CG_FS_FOPENFILE: return FS_FOpenFileByMode(VMA(1), VMA(2), args[3]); case CG_FS_READ: FS_Read(VMA(1), args[2], args[3]); return 0; case CG_FS_WRITE: return FS_Write(VMA(1), args[2], args[3]); case CG_FS_FCLOSEFILE: FS_FCloseFile(args[1]); return 0; case CG_FS_GETFILELIST: return FS_GetFileList(VMA(1), VMA(2), VMA(3), args[4]); case CG_FS_DELETEFILE: return FS_Delete(VMA(1)); case CG_SENDCONSOLECOMMAND: Cbuf_AddText(VMA(1)); return 0; case CG_ADDCOMMAND: CL_AddCgameCommand(VMA(1)); return 0; case CG_REMOVECOMMAND: Cmd_RemoveCommandSafe(VMA(1)); return 0; case CG_SENDCLIENTCOMMAND: CL_AddReliableCommand(VMA(1)); return 0; case CG_UPDATESCREEN: SCR_UpdateScreen(); return 0; case CG_CM_LOADMAP: CL_CM_LoadMap(VMA(1)); return 0; case CG_CM_NUMINLINEMODELS: return CM_NumInlineModels(); case CG_CM_INLINEMODEL: return CM_InlineModel(args[1]); case CG_CM_TEMPBOXMODEL: return CM_TempBoxModel(VMA(1), VMA(2), qfalse); case CG_CM_TEMPCAPSULEMODEL: return CM_TempBoxModel(VMA(1), VMA(2), qtrue); case CG_CM_POINTCONTENTS: return CM_PointContents(VMA(1), args[2]); case CG_CM_TRANSFORMEDPOINTCONTENTS: return CM_TransformedPointContents(VMA(1), args[2], VMA(3), VMA(4)); case CG_CM_BOXTRACE: CM_BoxTrace(VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qfalse); return 0; case CG_CM_CAPSULETRACE: CM_BoxTrace(VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qtrue); return 0; case CG_CM_TRANSFORMEDBOXTRACE: CM_TransformedBoxTrace(VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qfalse); return 0; case CG_CM_TRANSFORMEDCAPSULETRACE: CM_TransformedBoxTrace(VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qtrue); return 0; case CG_CM_MARKFRAGMENTS: return re.MarkFragments(args[1], VMA(2), VMA(3), args[4], VMA(5), args[6], VMA(7)); case CG_R_PROJECTDECAL: re.ProjectDecal(args[1], args[2], VMA(3), VMA(4), VMA(5), args[6], args[7]); return 0; case CG_R_CLEARDECALS: re.ClearDecals(); return 0; case CG_S_STARTSOUND: S_StartSound(VMA(1), args[2], args[3], args[4], args[5]); return 0; case CG_S_STARTSOUNDEX: S_StartSoundEx(VMA(1), args[2], args[3], args[4], args[5], args[6]); return 0; case CG_S_STARTLOCALSOUND: S_StartLocalSound(args[1], args[2], args[3]); return 0; case CG_S_CLEARLOOPINGSOUNDS: S_ClearLoopingSounds(); return 0; case CG_S_CLEARSOUNDS: if (args[1] == 0) { S_ClearSounds(qtrue, qfalse); } else if (args[1] == 1) { S_ClearSounds(qtrue, qtrue); } return 0; case CG_S_ADDLOOPINGSOUND: // FIXME handling of looping sounds changed S_AddLoopingSound(VMA(1), VMA(2), args[3], args[4], args[5], args[6]); return 0; case CG_S_ADDREALLOOPINGSOUND: S_AddRealLoopingSound(VMA(1), VMA(2), args[3], args[4], args[5], args[6]); return 0; case CG_S_STOPSTREAMINGSOUND: S_StopEntStreamingSound(args[1]); return 0; case CG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition(args[1], VMA(2)); return 0; // talking animations case CG_S_GETVOICEAMPLITUDE: return S_GetVoiceAmplitude(args[1]); case CG_S_GETSOUNDLENGTH: return S_GetSoundLength(args[1]); // for looped sound starts case CG_S_GETCURRENTSOUNDTIME: return S_GetCurrentSoundTime(); case CG_S_RESPATIALIZE: S_Respatialize(args[1], VMA(2), VMA(3), args[4]); return 0; case CG_S_REGISTERSOUND: return S_RegisterSound(VMA(1), args[2]); case CG_S_STARTBACKGROUNDTRACK: S_StartBackgroundTrack(VMA(1), VMA(2), args[3]); // added fadeup time return 0; case CG_S_FADESTREAMINGSOUND: S_FadeStreamingSound(VMF(1), args[2], args[3]); // added music/all-streaming options return 0; case CG_S_STARTSTREAMINGSOUND: return S_StartStreamingSound(VMA(1), VMA(2), args[3], args[4], args[5]); case CG_R_LOADWORLDMAP: re.LoadWorld(VMA(1)); return 0; case CG_R_REGISTERMODEL: return re.RegisterModel(VMA(1)); case CG_R_REGISTERSKIN: return re.RegisterSkin(VMA(1)); case CG_R_GETSKINMODEL: return re.GetSkinModel(args[1], VMA(2), VMA(3)); case CG_R_GETMODELSHADER: return re.GetShaderFromModel(args[1], args[2], args[3]); case CG_R_REGISTERSHADER: return re.RegisterShader(VMA(1)); case CG_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip(VMA(1)); case CG_R_REGISTERFONT: re.RegisterFont(VMA(1), args[2], VMA(3)); return 0; case CG_R_CLEARSCENE: re.ClearScene(); return 0; case CG_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene(VMA(1)); return 0; case CG_R_ADDPOLYTOSCENE: re.AddPolyToScene(args[1], args[2], VMA(3)); return 0; case CG_R_ADDPOLYSTOSCENE: re.AddPolysToScene(args[1], args[2], VMA(3), args[4]); return 0; case CG_R_ADDPOLYBUFFERTOSCENE: re.AddPolyBufferToScene(VMA(1)); return 0; case CG_R_ADDLIGHTTOSCENE: re.AddLightToScene(VMA(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), args[7], args[8]); return 0; case CG_R_ADDCORONATOSCENE: re.AddCoronaToScene(VMA(1), VMF(2), VMF(3), VMF(4), VMF(5), args[6], args[7]); return 0; case CG_R_SETFOG: re.SetFog(args[1], args[2], args[3], VMF(4), VMF(5), VMF(6), VMF(7)); return 0; case CG_R_SETGLOBALFOG: re.SetGlobalFog(args[1], args[2], VMF(3), VMF(4), VMF(5), VMF(6)); return 0; case CG_R_RENDERSCENE: re.RenderScene(VMA(1)); return 0; case CG_R_SAVEVIEWPARMS: re.SaveViewParms(); return 0; case CG_R_RESTOREVIEWPARMS: re.RestoreViewParms(); return 0; case CG_R_SETCOLOR: re.SetColor(VMA(1)); return 0; case CG_R_DRAWSTRETCHPIC: re.DrawStretchPic(VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9]); return 0; case CG_R_DRAWROTATEDPIC: re.DrawRotatedPic(VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9], VMF(10)); return 0; case CG_R_DRAWSTRETCHPIC_GRADIENT: re.DrawStretchPicGradient(VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9], VMA(10), args[11]); return 0; case CG_R_DRAW2DPOLYS: re.Add2dPolys(VMA(1), args[2], args[3]); return 0; case CG_R_MODELBOUNDS: re.ModelBounds(args[1], VMA(2), VMA(3)); return 0; case CG_R_LERPTAG: return re.LerpTag(VMA(1), VMA(2), VMA(3), args[4]); case CG_GETGLCONFIG: CL_GetGlconfig(VMA(1)); return 0; case CG_GETGAMESTATE: CL_GetGameState(VMA(1)); return 0; case CG_GETCURRENTSNAPSHOTNUMBER: CL_GetCurrentSnapshotNumber(VMA(1), VMA(2)); return 0; case CG_GETSNAPSHOT: return CL_GetSnapshot(args[1], VMA(2)); case CG_GETSERVERCOMMAND: return CL_GetServerCommand(args[1]); case CG_GETCURRENTCMDNUMBER: return CL_GetCurrentCmdNumber(); case CG_GETUSERCMD: return CL_GetUserCmd(args[1], VMA(2)); case CG_SETUSERCMDVALUE: CL_SetUserCmdValue(args[1], args[2], VMF(3), args[4]); return 0; case CG_SETCLIENTLERPORIGIN: CL_SetClientLerpOrigin(VMF(1), VMF(2), VMF(3)); return 0; case CG_MEMORY_REMAINING: return Hunk_MemoryRemaining(); case CG_KEY_ISDOWN: return Key_IsDown(args[1]); case CG_KEY_GETCATCHER: return Key_GetCatcher(); case CG_KEY_SETCATCHER: // Don't allow the cgame module to close the console Key_SetCatcher(args[1] | (Key_GetCatcher() & KEYCATCH_CONSOLE)); return 0; case CG_KEY_GETKEY: return Key_GetKey(VMA(1)); case CG_KEY_GETOVERSTRIKEMODE: return Key_GetOverstrikeMode(); case CG_KEY_SETOVERSTRIKEMODE: Key_SetOverstrikeMode(args[1]); return 0; case CG_MEMSET: return (intptr_t)memset(VMA(1), args[2], args[3]); case CG_MEMCPY: return (intptr_t)memcpy(VMA(1), VMA(2), args[3]); case CG_STRNCPY: return (intptr_t)strncpy(VMA(1), VMA(2), args[3]); case CG_SIN: return FloatAsInt(sin(VMF(1))); case CG_COS: return FloatAsInt(cos(VMF(1))); case CG_ATAN2: return FloatAsInt(atan2(VMF(1), VMF(2))); case CG_SQRT: return FloatAsInt(sqrt(VMF(1))); case CG_FLOOR: return FloatAsInt(floor(VMF(1))); case CG_CEIL: return FloatAsInt(ceil(VMF(1))); case CG_ACOS: return FloatAsInt(Q_acos(VMF(1))); case CG_PC_ADD_GLOBAL_DEFINE: return botlib_export->PC_AddGlobalDefine(VMA(1)); case CG_PC_LOAD_SOURCE: return botlib_export->PC_LoadSourceHandle(VMA(1)); case CG_PC_FREE_SOURCE: return botlib_export->PC_FreeSourceHandle(args[1]); case CG_PC_READ_TOKEN: return botlib_export->PC_ReadTokenHandle(args[1], VMA(2)); case CG_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine(args[1], VMA(2), VMA(3)); case CG_PC_UNREAD_TOKEN: botlib_export->PC_UnreadLastTokenHandle(args[1]); return 0; case CG_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case CG_REAL_TIME: return Com_RealTime(VMA(1)); case CG_SNAPVECTOR: Sys_SnapVector(VMA(1)); return 0; case CG_CIN_PLAYCINEMATIC: return CIN_PlayCinematic(VMA(1), args[2], args[3], args[4], args[5], args[6]); case CG_CIN_STOPCINEMATIC: return CIN_StopCinematic(args[1]); case CG_CIN_RUNCINEMATIC: return CIN_RunCinematic(args[1]); case CG_CIN_DRAWCINEMATIC: CIN_DrawCinematic(args[1]); return 0; case CG_CIN_SETEXTENTS: CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]); return 0; case CG_R_REMAP_SHADER: re.RemapShader(VMA(1), VMA(2), VMA(3)); return 0; case CG_TESTPRINTINT: Com_Printf("%s%li\n", (char *)VMA(1), (long)args[2]); return 0; case CG_TESTPRINTFLOAT: Com_Printf("%s%f\n", (char *)VMA(1), VMF(2)); return 0; case CG_GET_ENTITY_TOKEN: return re.GetEntityToken(VMA(1), args[2]); case CG_INGAME_POPUP: if (cls.state == CA_ACTIVE && !clc.demoplaying) { if (uivm) // can be called as the system is shutting down { VM_Call(uivm, UI_SET_ACTIVE_MENU, args[1]); } } return 0; case CG_KEY_GETBINDINGBUF: Key_GetBindingBuf(args[1], VMA(2), args[3]); return 0; case CG_KEY_SETBINDING: Key_SetBinding(args[1], VMA(2)); return 0; case CG_KEY_KEYNUMTOSTRINGBUF: Key_KeynumToStringBuf(args[1], VMA(2), args[3]); return 0; case CG_KEY_BINDINGTOKEYS: Key_GetBindingByString(VMA(1), VMA(2), VMA(3)); return 0; case CG_TRANSLATE_STRING: CL_TranslateString(VMA(1), VMA(2)); return 0; case CG_S_FADEALLSOUNDS: S_FadeAllSounds(VMF(1), args[2], args[3]); return 0; case CG_R_INPVS: return re.inPVS(VMA(1), VMA(2)); case CG_GETHUNKDATA: Com_GetHunkInfo(VMA(1), VMA(2)); return 0; // binary channel case CG_SENDMESSAGE: CL_SendBinaryMessage(VMA(1), args[2]); return 0; case CG_MESSAGESTATUS: return CL_BinaryMessageStatus(); case CG_R_LOADDYNAMICSHADER: return re.LoadDynamicShader(VMA(1), VMA(2)); case CG_R_RENDERTOTEXTURE: re.RenderToTexture(args[1], args[2], args[3], args[4], args[5]); return 0; case CG_R_GETTEXTUREID: return re.GetTextureId(VMA(1)); // flush gl rendering buffers case CG_R_FINISH: re.Finish(); return 0; case CG_LOADCAMERA: case CG_STARTCAMERA: case CG_STOPCAMERA: case CG_GETCAMERAINFO: case CG_PUMPEVENTLOOP: case CG_INGAME_CLOSEPOPUP: case CG_R_LIGHTFORPOINT: // re-added to avoid a crash when called - still in enum of cgameImport_t // This shows (developer 1) when the vanilla mod code is loaded or mods using obsolete system calls - see cases. Com_DPrintf("Obsolete cgame system trap: %ld\n", (long int) args[0]); return 0; default: Com_Error(ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0]); break; } return 0; }
/* ==================== CL_CgameSystemCalls The cgame module is making a system call ==================== */ intptr_t CL_CgameSystemCalls( intptr_t *args ) { switch( args[0] ) { case CG_PRINT: Com_Printf( "%s", VMA(1) ); return 0; case CG_FATAL_ERROR: Com_Error( ERR_DROP, "%s", VMA(1) ); return 0; case CG_MILLISECONDS: return Sys_Milliseconds(); case CG_CVAR_REGISTER: Cvar_Register( VMA(1), VMA(2), VMA(3), args[4] ); return 0; case CG_CVAR_UPDATE: Cvar_Update( VMA(1) ); return 0; case CG_CVAR_SET: Cvar_Set( VMA(1), VMA(2) ); return 0; case CG_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer( VMA(1), VMA(2), args[3] ); return 0; case CG_ARGC: return Cmd_Argc(); case CG_ARGV: Cmd_ArgvBuffer( args[1], VMA(2), args[3] ); return 0; case CG_ARGVI: return atoi( Cmd_Argv( args[1] ) ); case CG_ARGS: Cmd_ArgsBuffer( VMA(1), args[2] ); return 0; case CG_CMD_EXECUTETEXT: Cbuf_ExecuteText( args[1], VMA(2) ); return 0; case CG_FS_FOPENFILE: return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] ); case CG_FS_READ: FS_Read( VMA(1), args[2], args[3] ); return 0; case CG_FS_WRITE: FS_Write( VMA(1), args[2], args[3] ); return 0; case CG_FS_FCLOSEFILE: FS_FCloseFile( args[1] ); return 0; case CG_SENDCONSOLECOMMAND: Cbuf_AddText( VMA(1) ); return 0; case CG_FORWARDCOMMAND: VM_Call( uivm, UI_CONSOLE_COMMAND, cls.realtime ); return 0; case CG_ADDCOMMAND: CL_AddCgameCommand( VMA(1) ); return 0; case CG_REMOVECOMMAND: Cmd_RemoveCommand( VMA(1) ); return 0; case CG_SENDCLIENTCOMMAND: CL_AddReliableCommand( VMA(1) ); return 0; case CG_UPDATESCREEN: // this is used during lengthy level loading, so pump message loop // Com_EventLoop(); // FIXME: if a server restarts here, BAD THINGS HAPPEN! // We can't call Com_EventLoop here, a restart will crash and this _does_ happen // if there is a map change while we are downloading at pk3. // ZOID SCR_UpdateScreen(); return 0; case CG_CM_LOADMAP: CL_CM_LoadMap( VMA(1) ); return 0; case CG_CM_NUMINLINEMODELS: return CM_NumInlineModels(); case CG_CM_INLINEMODEL: return CM_InlineModel( args[1] ); case CG_CM_TEMPBOXMODEL: return CM_TempBoxModel( VMA(1), VMA(2), /*int capsule*/ qfalse ); case CG_CM_TEMPCAPSULEMODEL: return CM_TempBoxModel( VMA(1), VMA(2), /*int capsule*/ qtrue ); case CG_CM_POINTCONTENTS: return CM_PointContents( VMA(1), args[2] ); case CG_CM_TRANSFORMEDPOINTCONTENTS: return CM_TransformedPointContents( VMA(1), args[2], VMA(3), VMA(4) ); case CG_CM_BOXTRACE: CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qfalse ); return 0; case CG_CM_CAPSULETRACE: CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qtrue ); return 0; case CG_CM_TRANSFORMEDBOXTRACE: CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qfalse ); return 0; case CG_CM_TRANSFORMEDCAPSULETRACE: CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qtrue ); return 0; case CG_CM_MARKFRAGMENTS: return re.MarkFragments( args[1], VMA(2), VMA(3), args[4], VMA(5), args[6], VMA(7) ); case CG_S_STARTSOUND: S_StartSound( VMA(1), args[2], args[3], args[4] ); return 0; case CG_S_STARTLOCALSOUND: S_StartLocalSound( args[1], args[2] ); return 0; case CG_S_CLEARLOOPINGSOUNDS: S_ClearLoopingSounds(args[1]); return 0; case CG_S_ADDLOOPINGSOUND: S_AddLoopingSound( args[1], VMA(2), VMA(3), args[4] ); return 0; case CG_S_ADDREALLOOPINGSOUND: S_AddRealLoopingSound( args[1], VMA(2), VMA(3), args[4] ); return 0; case CG_S_STOPLOOPINGSOUND: S_StopLoopingSound( args[1] ); return 0; case CG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition( args[1], VMA(2) ); return 0; case CG_S_RESPATIALIZE: S_Respatialize( args[1], VMA(2), VMA(3), args[4] ); return 0; case CG_S_REGISTERSOUND: return S_RegisterSound( VMA(1), args[2] ); case CG_S_STARTBACKGROUNDTRACK: S_StartBackgroundTrack( VMA(1), VMA(2) ); return 0; case CG_R_LOADWORLDMAP: CL_R_LoadWorld( VMA( 1 ) ); return 0; case CG_R_REGISTERMODEL: return re.RegisterModel( VMA(1) ); case CG_R_REGISTERSKIN: return re.RegisterSkin( VMA(1) ); case CG_R_REGISTERSHADER: return re.RegisterShader( VMA(1) ); case CG_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip( VMA(1) ); case CG_R_REGISTERFONT: return re.RegisterFont( VMA(1) ); case CG_R_CLEARSCENE: re.ClearScene(); return 0; case CG_R_BUILDPOSE: { animGroupTransition_t trans; trans.animGroup = 0; trans.interp = 0; return re.BuildPose( args[1], VMA( 2 ), args[3], VMA( 4 ), args[5], NULL, 0, NULL, 0, &trans, 1 ); } case CG_R_BUILDPOSE2: return re.BuildPose( args[1], VMA( 2 ), 2, VMA( 3 ), 2, VMA( 4 ), 2, VMA( 5 ), 2, VMA( 6 ), 2 ); case CG_R_BUILDPOSE3: return re.BuildPose( args[1], VMA( 2 ), 1, 0, 0, VMA( 3 ), 1, 0, 0, VMA( 4 ), 1 ); case CG_R_LERPTAGFROMPOSE: return re.LerpTagFromPose( VMA( 1 ), args[2], args[3], VMA( 4 ) ); case CG_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene( VMA(1) ); return 0; case CG_R_ADDPOLYTOSCENE: re.AddPolyToScene( args[1], args[2], VMA(3), 1 ); return 0; case CG_R_ADDPOLYSTOSCENE: re.AddPolyToScene( args[1], args[2], VMA(3), args[4] ); return 0; case CG_R_MENUBEGINSURF: re.MenuBeginSurf( args[1] ); return 0; case CG_R_MENUENDSURF: re.MenuEndSurf(); return 0; case CG_R_LIGHTFORPOINT: return re.LightForPoint( VMA(1), VMA(2), VMA(3), VMA(4) ); case CG_R_ADDLIGHTTOSCENE: re.AddLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); return 0; case CG_R_ADDADDITIVELIGHTTOSCENE: re.AddAdditiveLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); return 0; case CG_R_RENDERSCENE: re.RenderScene( VMA(1) ); return 0; case CG_R_SETCOLOR: re.SetColor( VMA(1) ); return 0; case CG_R_DRAWSTRETCHPIC: re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), NULL, VMF(5), VMF(6), VMF(7), VMF(8), args[9] ); return 0; case CG_R_SHAPECREATE: { curve_t * c = VMA(1); int n = args[3]; int i; for ( i=0; i<n; i++ ) { c->pts = (vec2_t*)VM_ArgPtr((intptr_t)c->pts); c->uvs = (vec2_t*)VM_ArgPtr((intptr_t)c->uvs); c->colors = (vec4_t*)VM_ArgPtr((intptr_t)c->colors); c->indices = (short*)VM_ArgPtr((intptr_t)c->indices ); } return re.ShapeCreate( c, VMA( 2 ), n ); } case CG_R_SHAPEDRAW: re.ShapeDraw( args[1], args[2], VMA( 3 ) ); return 0; case CG_R_RENDERTEXT: CL_RenderText( VMA(1), VMF(2), VMA(3), VMA(4), args[5], (args[6])>>16, args[6]&0xFFFF, args[7], args[8], 0, args[9], VMA(10) ); return 0; case CG_R_GETFONT: memcpy( VMA(3), re.GetFontFromFontSet( args[1], VMF(2) ), sizeof(fontInfo_t) ); return 0; case CG_R_ROUNDRECT: SCR_FillRect( VMF(1), VMF(2), VMF(3), VMF(4), VMA(5), args[6] ); return 0; case CG_R_MODELBOUNDS: re.ModelBounds( args[1], VMA(2), VMA(3) ); return 0; case CG_R_LERPTAG: return re.LerpTag( VMA(1), args[2], args[3], args[4], VMF(5), VMA(6) ); case CG_GETGLCONFIG: CL_GetGlconfig( VMA(1) ); return 0; case CG_GETGAMESTATE: CL_GetGameState( VMA(1) ); return 0; case CG_GETCURRENTSNAPSHOTNUMBER: CL_GetCurrentSnapshotNumber( VMA(1), VMA(2) ); return 0; case CG_GETSNAPSHOT: return CL_GetSnapshot( args[1], VMA(2) ); case CG_GETSERVERCOMMAND: return CL_GetServerCommand( args[1] ); case CG_GETCURRENTCMDNUMBER: return CL_GetCurrentCmdNumber(); case CG_GETUSERCMD: return CL_GetUserCmd( args[1], VMA(2) ); case CG_SETUSERCMDVALUE: CL_SetUserCmdValue( args[1], VMF(2) ); return 0; case CG_MEMORY_REMAINING: return Hunk_MemoryRemaining(); case CG_KEY_ISDOWN: return Key_IsDown( args[1] ); case CG_KEY_GETCATCHER: return Key_GetCatcher(); case CG_KEY_SETCATCHER: Key_SetCatcher( args[1] ); return 0; case CG_KEY_GETKEY: return Key_GetKey( VMA(1) ); case CG_MEMSET: Com_Memset( VMA(1), args[2], args[3] ); return 0; case CG_MEMCPY: Com_Memcpy( VMA(1), VMA(2), args[3] ); return 0; case CG_STRNCPY: strncpy( VMA(1), VMA(2), args[3] ); return args[1]; case CG_SIN: return FloatAsInt( sin( VMF(1) ) ); case CG_COS: return FloatAsInt( cos( VMF(1) ) ); case CG_ATAN2: return FloatAsInt( atan2( VMF(1), VMF(2) ) ); case CG_SQRT: return FloatAsInt( sqrt( VMF(1) ) ); case CG_FLOOR: return FloatAsInt( floor( VMF(1) ) ); case CG_CEIL: return FloatAsInt( ceil( VMF(1) ) ); case CG_ACOS: return FloatAsInt( Q_acos( VMF(1) ) ); case CG_FMOD: return FloatAsInt( fmod( VMF(1),VMF(2) ) ); case CG_POW: return FloatAsInt( pow( VMF(1),VMF(2) ) ); case CG_ATAN: return FloatAsInt( atan( VMF(1) ) ); case CG_TAN: return FloatAsInt( tan( VMF(1)) ); case CG_PC_ADD_GLOBAL_DEFINE: return botlib_export->PC_AddGlobalDefine( VMA(1) ); case CG_PC_LOAD_SOURCE: return botlib_export->PC_LoadSourceHandle( VMA(1) ); case CG_PC_FREE_SOURCE: return botlib_export->PC_FreeSourceHandle( args[1] ); case CG_PC_READ_TOKEN: return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) ); case CG_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) ); case CG_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case CG_REAL_TIME: return Com_RealTime( VMA(1) ); case CG_SNAPVECTOR: Sys_SnapVector( VMA(1) ); return 0; case CG_UPDATEGAMESTATE: return CL_UpdateGameState( VMA(1) ); case CG_CIN_PLAYCINEMATIC: return CIN_PlayCinematic(VMA(1), args[2], args[3], args[4], args[5], args[6]); case CG_CIN_STOPCINEMATIC: return CIN_StopCinematic(args[1]); case CG_CIN_RUNCINEMATIC: return CIN_RunCinematic(args[1]); case CG_CIN_DRAWCINEMATIC: CIN_DrawCinematic(args[1]); return 0; case CG_CIN_SETEXTENTS: CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]); return 0; case CG_R_REMAP_SHADER: //ToDo: remove this trap return 0; /* case CG_LOADCAMERA: return loadCamera(VMA(1)); case CG_STARTCAMERA: startCamera(args[1]); return 0; case CG_GETCAMERAINFO: return getCameraInfo(args[1], VMA(2), VMA(3)); */ case CG_GET_ENTITY_TOKEN: return re.GetEntityToken( VMA(1), args[2] ); case CG_R_INPVS: return re.inPVS( VMA(1), VMA(2) ); case CG_Q_rand: return Rand_NextUInt32( &cl.db.rand ); case CG_SQL_LOADDB: { char * buffer; int length; length = FS_ReadFile( VMA(1), &buffer ); if ( length > 0 ) { sql_exec( &cl.db, buffer ); FS_FreeFile(buffer); } return 0; } break; case CG_SQL_EXEC: return sql_exec( &cl.db, VMA(1) ); case CG_SQL_PREPARE: return sql_prepare( &cl.db, VMA(1) ) != 0; case CG_SQL_BIND: return sql_bind( &cl.db, args ); case CG_SQL_BINDTEXT: return sql_bindtext( &cl.db, args[1], VMA(2) ); case CG_SQL_BINDINT: return sql_bindint( &cl.db, args[1], args[2] ); case CG_SQL_BINDARGS: { int i,n = Cmd_Argc(); for ( i=1; i<n; i++ ) { if ( !sql_bindtext( &cl.db, i, Cmd_Argv( i ) ) ) return 0; } } return 1; case CG_SQL_STEP: return sql_step( &cl.db ); case CG_SQL_COLUMNCOUNT: return sql_columncount( &cl.db ); case CG_SQL_COLUMNASTEXT: Q_strncpyz( VMA(1), sql_columnastext( &cl.db, args[3] ), args[2] ); break; case CG_SQL_COLUMNASINT: return sql_columnasint( &cl.db, args[1] ); case CG_SQL_COLUMNNAME: Q_strncpyz( VMA(1), sql_columnname( &cl.db, args[3] ), args[2] ); break; case CG_SQL_DONE: return sql_done( &cl.db ); case CG_SQL_COMPILE: return sql_compile( &cl.db, VMA(1) ); case CG_SQL_RUN: { char * buffer = VMA(1); int size = args[2]; int id = args[3]; int i; formatInfo_t * stmt = (formatInfo_t*)cl.db.stmts_byindex[ id ]; if ( stmt ) { sqlData_t params[ 3 ]; const char * r; for ( i=0; i<3; i++ ) { params[ i ].format = INTEGER; params[ i ].payload.integer = args[ 4+i ]; } r = sql_eval( &cl.db, stmt->print, 0, 0, 0, 0, params, 0 ).string; Q_strncpyz( buffer, r, size ); } else { buffer[ 0 ] = '\0'; } } break; default: assert(0); // bk010102 Com_Error( ERR_DROP, "Bad cgame system trap: %i", args[0] ); } return 0; }
/* =================== CL_HandleServerCommand CL_GetServerCommand =================== */ bool CL_HandleServerCommand(Str::StringRef text, std::string& newText) { static char bigConfigString[ BIG_INFO_STRING ]; Cmd::Args args(text); if (args.Argc() == 0) { return false; } auto cmd = args.Argv(0); int argc = args.Argc(); if (cmd == "disconnect") { // NERVE - SMF - allow server to indicate why they were disconnected if (argc >= 2) { Com_Error(errorParm_t::ERR_SERVERDISCONNECT, "Server disconnected: %s", args.Argv(1).c_str()); } else { Com_Error(errorParm_t::ERR_SERVERDISCONNECT, "Server disconnected"); } } // bcs0 to bcs2 are used by the server to send info strings that are bigger than the size of a packet. // See also SV_UpdateConfigStrings // bcs0 starts a new big config string // bcs1 continues it // bcs2 finishes it and feeds it back as a new command sent by the server (bcs0 makes it a cs command) if (cmd == "bcs0") { if (argc >= 3) { Com_sprintf(bigConfigString, BIG_INFO_STRING, "cs %s %s", args.Argv(1).c_str(), args.EscapedArgs(2).c_str()); } return false; } if (cmd == "bcs1") { if (argc >= 3) { const char* s = Cmd_QuoteString( args[2].c_str() ); if (strlen(bigConfigString) + strlen(s) >= BIG_INFO_STRING) { Com_Error(errorParm_t::ERR_DROP, "bcs exceeded BIG_INFO_STRING"); } Q_strcat(bigConfigString, sizeof(bigConfigString), s); } return false; } if (cmd == "bcs2") { if (argc >= 3) { const char* s = Cmd_QuoteString( args[2].c_str() ); if (strlen(bigConfigString) + strlen(s) + 1 >= BIG_INFO_STRING) { Com_Error(errorParm_t::ERR_DROP, "bcs exceeded BIG_INFO_STRING"); } Q_strcat(bigConfigString, sizeof(bigConfigString), s); Q_strcat(bigConfigString, sizeof(bigConfigString), "\""); newText = bigConfigString; return CL_HandleServerCommand(bigConfigString, newText); } return false; } if (cmd == "cs") { CL_ConfigstringModified(args); return true; } if (cmd == "map_restart") { // clear outgoing commands before passing // the restart to the cgame memset(cl.cmds, 0, sizeof(cl.cmds)); return true; } if (cmd == "popup") { // direct server to client popup request, bypassing cgame if (cls.state == connstate_t::CA_ACTIVE && !clc.demoplaying && argc >=1) { // TODO: Pass to the cgame } return false; } if (cmd == "pubkey_decrypt") { char buffer[ MAX_STRING_CHARS ] = "pubkey_identify "; NettleLength msg_len = MAX_STRING_CHARS - 16; mpz_t message; if (argc == 1) { Log::Notice("^3Server sent a pubkey_decrypt command, but sent nothing to decrypt!\n"); return false; } mpz_init_set_str(message, args.Argv(1).c_str(), 16); if (rsa_decrypt(&private_key, &msg_len, (unsigned char *) buffer + 16, message)) { nettle_mpz_set_str_256_u(message, msg_len, (unsigned char *) buffer + 16); mpz_get_str(buffer + 16, 16, message); CL_AddReliableCommand(buffer); } mpz_clear(message); return false; } return true; }
void DL_End( CURLcode res, CURLMcode resm ) { CURLMsg *msg; int msgs; if( dl_verbose->integer == 0 && dl_showprogress->integer == 2 && !curlm ) Com_Printf( "\n" ); if( curlm ) { // res = final download result while( ( msg = curl_multi_info_read( curlm, &msgs ) ) ) { if( msg->msg != CURLMSG_DONE ) { if( dl_error[0] == '\0' ) Q_strncpyz( dl_error, "Download Interrupted.", sizeof(dl_error) ); } else if( msg->easy_handle == curl ) { if( msg->data.result != CURLE_OK ); res = msg->data.result; } else { Com_Printf( "Invalid cURL handle.\n" ); } } curl_multi_cleanup( curlm ); curlm = NULL; } if( curl ) { curl_easy_cleanup( curl ); curl = NULL; } // get possible error messages if( !*dl_error && res != CURLE_OK ) Q_strncpyz( dl_error, curl_easy_strerror(res), sizeof(dl_error) ); if( !*dl_error && resm != CURLM_OK ) Q_strncpyz( dl_error, curl_multi_strerror(resm), sizeof(dl_error) ); if( !*dl_error && !f ) Q_strncpyz( dl_error, "File is not opened.", sizeof(dl_error) ); if (f) { FS_FCloseFile(f); f = 0; if (!*dl_error) { // download succeeded char dest[MAX_OSPATH]; Com_Printf("Download complete, restarting filesystem.\n"); Q_strncpyz(dest, path, strlen(path)-3); // -4 +1 for the trailing \0 Q_strcat(dest, sizeof(dest), ".pk3"); if (!FS_FileExists(dest)) { FS_SV_Rename(path, dest); FS_Restart(clc.checksumFeed); if (dl_showmotd->integer && *motd) { Com_Printf("Server motd: %s\n", motd); } } else { // normally such errors should be caught upon starting the transfer. Anyway better do // it here again - the filesystem might have changed, plus this may help contain some // bugs / exploitable flaws in the code. Com_Printf("Failed to copy downloaded file to its location - file already exists.\n"); FS_HomeRemove(path); } } else { FS_HomeRemove(path); } } Cvar_Set( "cl_downloadName", "" ); // hide the ui downloading screen Cvar_SetValue( "cl_downloadSize", 0 ); Cvar_SetValue( "cl_downloadCount", 0 ); Cvar_SetValue( "cl_downloadTime", 0 ); Cvar_Set( "cl_downloadMotd", "" ); if( *dl_error ) { if( clc.state == CA_CONNECTED ) Com_Error( ERR_DROP, "%s\n", dl_error ); // download error while connecting, can not continue loading else Com_Printf( "%s\n", dl_error ); // download error while in game, do not disconnect *dl_error = '\0'; } else { if (strlen(Cvar_VariableString("cl_downloadDemo"))) { Cbuf_AddText( va("demo %s\n", Cvar_VariableString("cl_downloadDemo") ) ); // download completed, request new gamestate to check possible new map if we are not already in game } else if( clc.state == CA_CONNECTED) CL_AddReliableCommand( "donedl", qfalse); // get new gamestate info from server } }
intptr_t CL_CgameSystemCalls( intptr_t *args ) { if( cls.cgInterface == 2 && args[0] >= CG_R_SETCLIPREGION && args[0] < CG_MEMSET ) { if( args[0] < CG_S_STOPBACKGROUNDTRACK - 1 ) args[0] += 1; else if( args[0] < CG_S_STOPBACKGROUNDTRACK + 4 ) args[0] += CG_PARSE_ADD_GLOBAL_DEFINE - CG_S_STOPBACKGROUNDTRACK + 1; else if( args[0] < CG_PARSE_ADD_GLOBAL_DEFINE + 4 ) args[0] -= 4; else if( args[0] >= CG_PARSE_SOURCE_FILE_AND_LINE && args[0] <= CG_S_SOUNDDURATION ) args[0] = CG_PARSE_SOURCE_FILE_AND_LINE - 1337 - args[0] ; } switch( args[0] ) { case CG_PRINT: Com_Printf( "%s", (const char*)VMA(1) ); return 0; case CG_ERROR: if( probingCG ) { cls.cgInterface = 2; // this is a 1.1.0 cgame return 0; } Com_Error( ERR_DROP, "%s", (const char*)VMA(1) ); return 0; case CG_MILLISECONDS: return Sys_Milliseconds(); case CG_CVAR_REGISTER: Cvar_Register( (vmCvar_t*)VMA(1), (const char*)VMA(2), (const char*)VMA(3), args[4] ); return 0; case CG_CVAR_UPDATE: Cvar_Update( (vmCvar_t*)VMA(1) ); return 0; case CG_CVAR_SET: Cvar_SetSafe( (const char*)VMA(1), (const char*)VMA(2) ); return 0; case CG_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer( (const char*)VMA(1), (char*)VMA(2), args[3] ); return 0; case CG_ARGC: return Cmd_Argc(); case CG_ARGV: Cmd_ArgvBuffer( args[1], (char*)VMA(2), args[3] ); return 0; case CG_ARGS: Cmd_ArgsBuffer( (char*)VMA(1), args[2] ); return 0; case CG_LITERAL_ARGS: Cmd_LiteralArgsBuffer( (char*)VMA(1), args[2] ); return 0; case CG_FS_FOPENFILE: return FS_FOpenFileByMode( (const char*)VMA(1), (fileHandle_t*)VMA(2), (FS_Mode)args[3] ); case CG_FS_READ: FS_Read( VMA(1), args[2], args[3] ); return 0; case CG_FS_WRITE: FS_Write( VMA(1), args[2], args[3] ); return 0; case CG_FS_FCLOSEFILE: FS_FCloseFile( args[1] ); return 0; case CG_FS_SEEK: return FS_Seek( (fileHandle_t)args[1], args[2], (FS_Origin)args[3] ); case CG_FS_GETFILELIST: return FS_GetFileList( (const char*)VMA(1), (const char*)VMA(2), (char*)VMA(3), args[4] ); case CG_SENDCONSOLECOMMAND: Cbuf_AddText( (const char*)VMA(1) ); return 0; case CG_ADDCOMMAND: Cmd_AddCommand( (const char*)VMA(1), NULL ); return 0; case CG_REMOVECOMMAND: Cmd_RemoveCommandSafe( (const char*)VMA(1) ); return 0; case CG_SENDCLIENTCOMMAND: CL_AddReliableCommand((const char*)VMA(1), false); return 0; case CG_UPDATESCREEN: // this is used during lengthy level loading, so pump message loop // Com_EventLoop(); // FIXME: if a server restarts here, BAD THINGS HAPPEN! // We can't call Com_EventLoop here, a restart will crash and this _does_ happen // if there is a map change while we are downloading at pk3. // ZOID SCR_UpdateScreen(); return 0; case CG_CM_LOADMAP: CL_CM_LoadMap( (const char*)VMA(1) ); return 0; case CG_CM_NUMINLINEMODELS: return CM_NumInlineModels(); case CG_CM_INLINEMODEL: return CM_InlineModel( args[1] ); case CG_CM_TEMPBOXMODEL: return CM_TempBoxModel( (const float*)VMA(1), (const float*)VMA(2), false ); case CG_CM_TEMPCAPSULEMODEL: return CM_TempBoxModel( (const float*)VMA(1), (const float*)VMA(2), true ); case CG_CM_POINTCONTENTS: return CM_PointContents( (const float*)VMA(1), args[2] ); case CG_CM_TRANSFORMEDPOINTCONTENTS: return CM_TransformedPointContents( (const float*)VMA(1), (clipHandle_t)args[2], (const float*)VMA(3), (const float*)VMA(4) ); case CG_CM_BOXTRACE: CM_BoxTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3), (float*)VMA(4), (float*)VMA(5), (clipHandle_t)args[6], args[7], TT_AABB ); return 0; case CG_CM_CAPSULETRACE: CM_BoxTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3), (float*)VMA(4), (float*)VMA(5), (clipHandle_t)args[6], args[7], TT_CAPSULE ); return 0; case CG_CM_TRANSFORMEDBOXTRACE: CM_TransformedBoxTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3), (float*)VMA(4), (float*)VMA(5), (clipHandle_t)args[6], args[7], (const float*)VMA(8), (const float*)VMA(9), TT_AABB ); return 0; case CG_CM_TRANSFORMEDCAPSULETRACE: CM_TransformedBoxTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3), (float*)VMA(4), (float*)VMA(5), (clipHandle_t)args[6], args[7], (const float*)VMA(8), (const float*)VMA(9), TT_CAPSULE ); return 0; case CG_CM_BISPHERETRACE: CM_BiSphereTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3), VMF(4), VMF(5), (clipHandle_t)args[6], args[7] ); return 0; case CG_CM_TRANSFORMEDBISPHERETRACE: CM_TransformedBiSphereTrace( (trace_t*)VMA(1), (const float*)VMA(2), (const float*)VMA(3), VMF(4), VMF(5), (clipHandle_t)args[6], args[7], (const float*)VMA(8) ); return 0; case CG_CM_MARKFRAGMENTS: { float (&arg2)[3][3] = *reinterpret_cast<float (*)[3][3]>(VMA(2)); return re.MarkFragments( args[1], arg2, (const float*)VMA(3), args[4], (float*)VMA(5), args[6], (markFragment_t*)VMA(7) ); } case CG_S_STARTSOUND: S_StartSound( (float*)VMA(1), args[2], args[3], (sfxHandle_t)args[4] ); return 0; case CG_S_STARTLOCALSOUND: S_StartLocalSound( (sfxHandle_t)args[1], args[2] ); return 0; case CG_S_CLEARLOOPINGSOUNDS: S_ClearLoopingSounds( (bool)args[1] ); return 0; case CG_S_ADDLOOPINGSOUND: S_AddLoopingSound( args[1], (const float*)VMA(2), (const float*)VMA(3), (sfxHandle_t)args[4] ); return 0; case CG_S_ADDREALLOOPINGSOUND: S_AddRealLoopingSound( args[1], (const float*)VMA(2), (const float*)VMA(3), (sfxHandle_t)args[4] ); return 0; case CG_S_STOPLOOPINGSOUND: S_StopLoopingSound( args[1] ); return 0; case CG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition( args[1], (const float*)VMA(2) ); return 0; case CG_S_RESPATIALIZE: { float (&arg3)[3][3] = *reinterpret_cast<float (*)[3][3]>(VMA(3)); S_Respatialize( args[1], (const float*)VMA(2), arg3, args[4] ); return 0; } case CG_S_REGISTERSOUND: return S_RegisterSound( (const char*)VMA(1), (bool)args[2] ); case CG_S_SOUNDDURATION: return S_SoundDuration( args[1] ); case CG_S_STARTBACKGROUNDTRACK: S_StartBackgroundTrack( (const char*)VMA(1), (const char*)VMA(2) ); return 0; case CG_R_LOADWORLDMAP: re.LoadWorld( (const char*)VMA(1) ); return 0; case CG_R_REGISTERMODEL: return re.RegisterModel( (const char*)VMA(1) ); case CG_R_REGISTERSKIN: return re.RegisterSkin( (const char*)VMA(1) ); case CG_R_REGISTERSHADER: return re.RegisterShader( (const char*)VMA(1) ); case CG_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip( (const char*)VMA(1) ); case CG_R_REGISTERFONT: re.RegisterFont( (const char*)VMA(1), args[2], (fontInfo_t*)VMA(3)); return 0; case CG_R_CLEARSCENE: re.ClearScene(); return 0; case CG_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene( (const refEntity_t*)VMA(1) ); return 0; case CG_R_ADDPOLYTOSCENE: re.AddPolyToScene( (qhandle_t)args[1], args[2], (const polyVert_t*)VMA(3), 1 ); return 0; case CG_R_ADDPOLYSTOSCENE: re.AddPolyToScene( (qhandle_t)args[1], args[2], (const polyVert_t*)VMA(3), args[4] ); return 0; case CG_R_LIGHTFORPOINT: return re.LightForPoint( (float*)VMA(1), (float*)VMA(2), (float*)VMA(3), (float*)VMA(4) ); case CG_R_ADDLIGHTTOSCENE: re.AddLightToScene( (const float*)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); return 0; case CG_R_ADDADDITIVELIGHTTOSCENE: re.AddAdditiveLightToScene( (const float*)VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); return 0; case CG_R_RENDERSCENE: re.RenderScene( (const refdef_t*)VMA(1) ); return 0; case CG_R_SETCOLOR: re.SetColor( (const float*)VMA(1) ); return 0; case CG_R_SETCLIPREGION: re.SetClipRegion( (const float*)VMA(1) ); return 0; case CG_R_DRAWSTRETCHPIC: re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), (qhandle_t)args[9] ); return 0; case CG_R_MODELBOUNDS: re.ModelBounds( (qhandle_t)args[1], (float*)VMA(2), (float*)VMA(3) ); return 0; case CG_R_LERPTAG: return re.LerpTag( (orientation_t*)VMA(1), args[2], args[3], args[4], VMF(5), (const char*)VMA(6) ); case CG_GETGLCONFIG: CL_GetGlconfig( (glconfig_t*)VMA(1) ); return 0; case CG_GETGAMESTATE: CL_GetGameState( (gameState_t*)VMA(1) ); return 0; case CG_GETCURRENTSNAPSHOTNUMBER: CL_GetCurrentSnapshotNumber( (int*)VMA(1), (int*)VMA(2) ); return 0; case CG_GETSNAPSHOT: return CL_GetSnapshot( args[1], (snapshot_t*)VMA(2) ); case CG_GETSERVERCOMMAND: return CL_GetServerCommand( args[1] ); case CG_GETCURRENTCMDNUMBER: return CL_GetCurrentCmdNumber(); case CG_GETUSERCMD: return CL_GetUserCmd( args[1], (usercmd_t*)VMA(2) ); case CG_SETUSERCMDVALUE: CL_SetUserCmdValue( args[1], VMF(2) ); return 0; case CG_MEMORY_REMAINING: return Hunk_MemoryRemaining(); case CG_KEY_ISDOWN: return Key_IsDown( args[1] ); case CG_KEY_GETCATCHER: return Key_GetCatcher(); case CG_KEY_SETCATCHER: // don't allow the cgame module to toggle the console Key_SetCatcher( ( args[1] & ~KEYCATCH_CONSOLE ) | ( Key_GetCatcher() & KEYCATCH_CONSOLE ) ); return 0; case CG_KEY_GETKEY: return Key_GetKey( (const char*)VMA(1) ); case CG_GETDEMOSTATE: return CL_DemoState( ); case CG_GETDEMOPOS: return CL_DemoPos( ); case CG_GETDEMONAME: CL_DemoName( (char*)VMA(1), args[2] ); return 0; case CG_KEY_KEYNUMTOSTRINGBUF: Key_KeynumToStringBuf( args[1], (char*)VMA(2), args[3] ); return 0; case CG_KEY_GETBINDINGBUF: Key_GetBindingBuf( args[1], (char*)VMA(2), args[3] ); return 0; case CG_KEY_SETBINDING: Key_SetBinding( args[1], (const char*)VMA(2) ); return 0; case CG_PARSE_ADD_GLOBAL_DEFINE: return Parse_AddGlobalDefine( (char*)VMA(1) ); case CG_PARSE_LOAD_SOURCE: return Parse_LoadSourceHandle( (const char*)VMA(1) ); case CG_PARSE_FREE_SOURCE: return Parse_FreeSourceHandle( args[1] ); case CG_PARSE_READ_TOKEN: return Parse_ReadTokenHandle( args[1], (pc_token_t*)VMA(2) ); case CG_PARSE_SOURCE_FILE_AND_LINE: return Parse_SourceFileAndLine( args[1], (char*)VMA(2), (int*)VMA(3) ); case CG_KEY_SETOVERSTRIKEMODE: Key_SetOverstrikeMode( (bool)args[1] ); return 0; case CG_KEY_GETOVERSTRIKEMODE: return Key_GetOverstrikeMode( ); case CG_FIELD_COMPLETELIST: Field_CompleteList( (char*)VMA(1) ); return 0; case CG_MEMSET: ::memset( VMA(1), args[2], args[3] ); return 0; case CG_MEMCPY: ::memcpy( VMA(1), VMA(2), args[3] ); return 0; case CG_STRNCPY: safe_strncpy( (char*)VMA(1), (const char*)VMA(2), args[3] ); return args[1]; case CG_SIN: return FloatAsInt( sin( VMF(1) ) ); case CG_COS: return FloatAsInt( cos( VMF(1) ) ); case CG_ATAN2: return FloatAsInt( atan2( VMF(1), VMF(2) ) ); case CG_SQRT: return FloatAsInt( sqrt( VMF(1) ) ); case CG_FLOOR: return FloatAsInt( floor( VMF(1) ) ); case CG_CEIL: return FloatAsInt( ceil( VMF(1) ) ); case CG_ACOS: return FloatAsInt( Q_acos( VMF(1) ) ); case CG_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case CG_REAL_TIME: return Com_RealTime( (qtime_t*)VMA(1) ); case CG_SNAPVECTOR: Q_SnapVector((float*)VMA(1)); return 0; case CG_CIN_PLAYCINEMATIC: return CIN_PlayCinematic((const char*)VMA(1), args[2], args[3], args[4], args[5], args[6]); case CG_CIN_STOPCINEMATIC: return CIN_StopCinematic(args[1]); case CG_CIN_RUNCINEMATIC: return CIN_RunCinematic(args[1]); case CG_CIN_DRAWCINEMATIC: CIN_DrawCinematic(args[1]); return 0; case CG_CIN_SETEXTENTS: CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]); return 0; case CG_R_REMAP_SHADER: re.RemapShader( (const char*)VMA(1), (const char*)VMA(2), (const char*)VMA(3) ); return 0; case CG_GET_ENTITY_TOKEN: return re.GetEntityToken( (char*)VMA(1), args[2] ); case CG_R_INPVS: return re.inPVS( (const float*)VMA(1), (const float*)VMA(2) ); default: assert(0); Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] ); } return 0; }
/* * CL_DownloadRequest * * Request file download * return false if couldn't request it for some reason * Files with .pk3 or .pak extension have to have gamedir attached * Other files must not have gamedir */ bool CL_DownloadRequest( const char *filename, bool requestpak ) { if( cls.download.requestname ) { Com_Printf( "Can't download: %s. Download already in progress.\n", filename ); return false; } if( !COM_ValidateRelativeFilename( filename ) ) { Com_Printf( "Can't download: %s. Invalid filename.\n", filename ); return false; } if( FS_CheckPakExtension( filename ) ) { if( FS_PakFileExists( filename ) ) { Com_Printf( "Can't download: %s. File already exists.\n", filename ); return false; } if( !Q_strnicmp( COM_FileBase( filename ), "modules", strlen( "modules" ) ) ) { if( !CL_CanDownloadModules() ) return false; } } else { if( FS_FOpenFile( filename, NULL, FS_READ ) != -1 ) { Com_Printf( "Can't download: %s. File already exists.\n", filename ); return false; } if( !requestpak ) { const char *extension; // only allow demo downloads extension = COM_FileExtension( filename ); if( !extension || Q_stricmp( extension, APP_DEMO_EXTENSION_STR ) ) { Com_Printf( "Can't download, got arbitrary file type: %s\n", filename ); return false; } } } if( cls.socket->type == SOCKET_LOOPBACK ) { Com_DPrintf( "Can't download: %s. Loopback server.\n", filename ); return false; } Com_Printf( "Asking to download: %s\n", filename ); cls.download.requestpak = requestpak; cls.download.requestname = Mem_ZoneMalloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); Q_strncpyz( cls.download.requestname, filename, sizeof( char ) * ( strlen( filename ) + 1 ) ); cls.download.timeout = Sys_Milliseconds() + 5000; CL_AddReliableCommand( va( "download %i \"%s\"", requestpak, filename ) ); return true; }
intptr_t CL_CgameSystemCalls( intptr_t *args ) { #ifndef __NO_JK2 if( com_jk2 && com_jk2->integer ) { args[0] = (intptr_t)CL_ConvertJK2SysCall((cgameJK2Import_t)args[0]); } #endif switch( args[0] ) { case CG_PRINT: Com_Printf( "%s", VMA(1) ); return 0; case CG_ERROR: Com_Error( ERR_DROP, S_COLOR_RED"%s", VMA(1) ); return 0; case CG_MILLISECONDS: return Sys_Milliseconds(); case CG_CVAR_REGISTER: Cvar_Register( (vmCvar_t *) VMA(1), (const char *) VMA(2), (const char *) VMA(3), args[4] ); return 0; case CG_CVAR_UPDATE: Cvar_Update( (vmCvar_t *) VMA(1) ); return 0; case CG_CVAR_SET: Cvar_Set( (const char *) VMA(1), (const char *) VMA(2) ); return 0; case CG_ARGC: return Cmd_Argc(); case CG_ARGV: Cmd_ArgvBuffer( args[1], (char *) VMA(2), args[3] ); return 0; case CG_ARGS: Cmd_ArgsBuffer( (char *) VMA(1), args[2] ); return 0; case CG_FS_FOPENFILE: return FS_FOpenFileByMode( (const char *) VMA(1), (int *) VMA(2), (fsMode_t) args[3] ); case CG_FS_READ: FS_Read( VMA(1), args[2], args[3] ); return 0; case CG_FS_WRITE: FS_Write( VMA(1), args[2], args[3] ); return 0; case CG_FS_FCLOSEFILE: FS_FCloseFile( args[1] ); return 0; case CG_SENDCONSOLECOMMAND: Cbuf_AddText( (const char *) VMA(1) ); return 0; case CG_ADDCOMMAND: CL_AddCgameCommand( (const char *) VMA(1) ); return 0; case CG_SENDCLIENTCOMMAND: CL_AddReliableCommand( (const char *) VMA(1) ); return 0; case CG_UPDATESCREEN: // this is used during lengthy level loading, so pump message loop Com_EventLoop(); // FIXME: if a server restarts here, BAD THINGS HAPPEN! SCR_UpdateScreen(); return 0; case CG_RMG_INIT: /* if (!com_sv_running->integer) { // don't do this if we are connected locally if (!TheRandomMissionManager) { TheRandomMissionManager = new CRMManager; } TheRandomMissionManager->SetLandScape( cmg.landScapes[args[1]] ); TheRandomMissionManager->LoadMission(qfalse); TheRandomMissionManager->SpawnMission(qfalse); cmg.landScapes[args[1]]->UpdatePatches(); } */ //this is SP.. I guess we're always the client and server. // cl.mRMGChecksum = cm.landScapes[args[1]]->get_rand_seed(); RM_CreateRandomModels(args[1], (const char *)VMA(2)); //cmg.landScapes[args[1]]->rand_seed(cl.mRMGChecksum); // restore it, in case we do a vid restart cmg.landScape->rand_seed(cmg.landScape->get_rand_seed()); // TheRandomMissionManager->CreateMap(); return 0; case CG_CM_REGISTER_TERRAIN: return CM_RegisterTerrain((const char *)VMA(1), false)->GetTerrainId(); case CG_RE_INIT_RENDERER_TERRAIN: re.InitRendererTerrain((const char *)VMA(1)); return 0; case CG_CM_LOADMAP: CL_CM_LoadMap( (const char *) VMA(1), args[2] ); return 0; case CG_CM_NUMINLINEMODELS: return CM_NumInlineModels(); case CG_CM_INLINEMODEL: return CM_InlineModel( args[1] ); case CG_CM_TEMPBOXMODEL: return CM_TempBoxModel( (const float *) VMA(1), (const float *) VMA(2) );//, (int) VMA(3) ); case CG_CM_POINTCONTENTS: return CM_PointContents( (float *)VMA(1), args[2] ); case CG_CM_TRANSFORMEDPOINTCONTENTS: return CM_TransformedPointContents( (const float *) VMA(1), args[2], (const float *) VMA(3), (const float *) VMA(4) ); case CG_CM_BOXTRACE: CM_BoxTrace( (trace_t *) VMA(1), (const float *) VMA(2), (const float *) VMA(3), (const float *) VMA(4), (const float *) VMA(5), args[6], args[7] ); return 0; case CG_CM_TRANSFORMEDBOXTRACE: CM_TransformedBoxTrace( (trace_t *) VMA(1), (const float *) VMA(2), (const float *) VMA(3), (const float *) VMA(4), (const float *) VMA(5), args[6], args[7], (const float *) VMA(8), (const float *) VMA(9) ); return 0; case CG_CM_MARKFRAGMENTS: return re.MarkFragments( args[1], (float(*)[3]) VMA(2), (const float *) VMA(3), args[4], (float *) VMA(5), args[6], (markFragment_t *) VMA(7) ); case CG_CM_SNAPPVS: CM_SnapPVS((float(*))VMA(1),(byte *) VMA(2)); return 0; case CG_S_STOPSOUNDS: S_StopSounds( ); return 0; case CG_S_STARTSOUND: // stops an ERR_DROP internally if called illegally from game side, but note that it also gets here // legally during level start where normally the internal s_soundStarted check would return. So ok to hit this. if (!cls.cgameStarted){ return 0; } S_StartSound( (float *) VMA(1), args[2], (soundChannel_t)args[3], args[4] ); return 0; case CG_S_UPDATEAMBIENTSET: // stops an ERR_DROP internally if called illegally from game side, but note that it also gets here // legally during level start where normally the internal s_soundStarted check would return. So ok to hit this. if (!cls.cgameStarted){ return 0; } S_UpdateAmbientSet( (const char *) VMA(1), (float *) VMA(2) ); return 0; case CG_S_ADDLOCALSET: return S_AddLocalSet( (const char *) VMA(1), (float *) VMA(2), (float *) VMA(3), args[4], args[5] ); case CG_AS_PARSESETS: AS_ParseSets(); return 0; case CG_AS_ADDENTRY: AS_AddPrecacheEntry( (const char *) VMA(1) ); return 0; case CG_AS_GETBMODELSOUND: return AS_GetBModelSound( (const char *) VMA(1), args[2] ); case CG_S_STARTLOCALSOUND: // stops an ERR_DROP internally if called illegally from game side, but note that it also gets here // legally during level start where normally the internal s_soundStarted check would return. So ok to hit this. if (!cls.cgameStarted){ return 0; } S_StartLocalSound( args[1], args[2] ); return 0; case CG_S_CLEARLOOPINGSOUNDS: S_ClearLoopingSounds(); return 0; case CG_S_ADDLOOPINGSOUND: // stops an ERR_DROP internally if called illegally from game side, but note that it also gets here // legally during level start where normally the internal s_soundStarted check would return. So ok to hit this. if (!cls.cgameStarted){ return 0; } S_AddLoopingSound( args[1], (const float *) VMA(2), (const float *) VMA(3), args[4], (soundChannel_t)args[5] ); return 0; case CG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition( args[1], (const float *) VMA(2) ); return 0; case CG_S_RESPATIALIZE: S_Respatialize( args[1], (const float *) VMA(2), (float(*)[3]) VMA(3), args[4] ); return 0; case CG_S_REGISTERSOUND: return S_RegisterSound( (const char *) VMA(1) ); case CG_S_STARTBACKGROUNDTRACK: S_StartBackgroundTrack( (const char *) VMA(1), (const char *) VMA(2), args[3]); return 0; case CG_S_GETSAMPLELENGTH: return S_GetSampleLengthInMilliSeconds( args[1]); case CG_R_LOADWORLDMAP: re.LoadWorld( (const char *) VMA(1) ); return 0; case CG_R_REGISTERMODEL: return re.RegisterModel( (const char *) VMA(1) ); case CG_R_REGISTERSKIN: return re.RegisterSkin( (const char *) VMA(1) ); case CG_R_REGISTERSHADER: return re.RegisterShader( (const char *) VMA(1) ); case CG_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip( (const char *) VMA(1) ); case CG_R_REGISTERFONT: return re.RegisterFont( (const char *) VMA(1) ); case CG_R_FONTSTRLENPIXELS: return re.Font_StrLenPixels( (const char *) VMA(1), args[2], VMF(3) ); case CG_R_FONTSTRLENCHARS: return re.Font_StrLenChars( (const char *) VMA(1) ); case CG_R_FONTHEIGHTPIXELS: return re.Font_HeightPixels( args[1], VMF(2) ); case CG_R_FONTDRAWSTRING: re.Font_DrawString(args[1],args[2], (const char *) VMA(3), (float*)args[4], args[5], args[6], VMF(7)); return 0; case CG_LANGUAGE_ISASIAN: return re.Language_IsAsian(); case CG_LANGUAGE_USESSPACES: return re.Language_UsesSpaces(); case CG_ANYLANGUAGE_READFROMSTRING: return re.AnyLanguage_ReadCharFromString( (char *) VMA(1), (int *) VMA(2), (qboolean *) VMA(3) ); case CG_ANYLANGUAGE_READFROMSTRING2: return re.AnyLanguage_ReadCharFromString2( (char **) VMA(1), (qboolean *) VMA(3) ); case CG_R_SETREFRACTIONPROP: *(re.tr_distortionAlpha()) = VMF(1); *(re.tr_distortionStretch()) = VMF(2); *(re.tr_distortionPrePost()) = (qboolean)args[3]; *(re.tr_distortionNegate()) = (qboolean)args[4]; return 0; case CG_R_CLEARSCENE: re.ClearScene(); return 0; case CG_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene( (const refEntity_t *) VMA(1) ); return 0; case CG_R_INPVS: return re.R_inPVS((float *) VMA(1), (float *) VMA(2)); case CG_R_GETLIGHTING: return re.GetLighting( (const float * ) VMA(1), (float *) VMA(2), (float *) VMA(3), (float *) VMA(4) ); case CG_R_ADDPOLYTOSCENE: re.AddPolyToScene( args[1], args[2], (const polyVert_t *) VMA(3) ); return 0; case CG_R_ADDLIGHTTOSCENE: #ifdef VV_LIGHTING VVLightMan.RE_AddLightToScene ( (const float *) VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); #else re.AddLightToScene( (const float *) VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); #endif return 0; case CG_R_RENDERSCENE: re.RenderScene( (const refdef_t *) VMA(1) ); return 0; case CG_R_SETCOLOR: re.SetColor( (const float *) VMA(1) ); return 0; case CG_R_DRAWSTRETCHPIC: re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9] ); return 0; // The below was commented out for whatever reason... /me shrugs --eez case CG_R_DRAWSCREENSHOT: re.DrawStretchRaw( VMF(1), VMF(2), VMF(3), VMF(4), SG_SCR_WIDTH, SG_SCR_HEIGHT, SCR_GetScreenshot(0), 0, qtrue); return 0; case CG_R_MODELBOUNDS: re.ModelBounds( args[1], (float *) VMA(2), (float *) VMA(3) ); return 0; case CG_R_LERPTAG: re.LerpTag( (orientation_t *) VMA(1), args[2], args[3], args[4], VMF(5), (const char *) VMA(6) ); return 0; case CG_R_DRAWROTATEPIC: re.DrawRotatePic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), VMF(9), args[10] ); return 0; case CG_R_DRAWROTATEPIC2: re.DrawRotatePic2( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), VMF(9), args[10] ); return 0; case CG_R_SETRANGEFOG: // FIXME: Figure out if this is how it's done in MP :S --eez /*if (tr.rangedFog <= 0.0f) { g_oldRangedFog = tr.rangedFog; } tr.rangedFog = VMF(1); if (tr.rangedFog == 0.0f && g_oldRangedFog) { //restore to previous state if applicable tr.rangedFog = g_oldRangedFog; }*/ re.SetRangedFog( VMF( 1 ) ); return 0; case CG_R_LA_GOGGLES: re.LAGoggles(); return 0; case CG_R_SCISSOR: re.Scissor( VMF(1), VMF(2), VMF(3), VMF(4)); return 0; case CG_GETGLCONFIG: CL_GetGlconfig( (glconfig_t *) VMA(1) ); return 0; case CG_GETGAMESTATE: CL_GetGameState( (gameState_t *) VMA(1) ); return 0; case CG_GETCURRENTSNAPSHOTNUMBER: CL_GetCurrentSnapshotNumber( (int *) VMA(1), (int *) VMA(2) ); return 0; case CG_GETSNAPSHOT: return CL_GetSnapshot( args[1], (snapshot_t *) VMA(2) ); case CG_GETDEFAULTSTATE: return CL_GetDefaultState(args[1], (entityState_t *)VMA(2)); case CG_GETSERVERCOMMAND: return CL_GetServerCommand( args[1] ); case CG_GETCURRENTCMDNUMBER: return CL_GetCurrentCmdNumber(); case CG_GETUSERCMD: return CL_GetUserCmd( args[1], (usercmd_s *) VMA(2) ); case CG_SETUSERCMDVALUE: CL_SetUserCmdValue( args[1], VMF(2), VMF(3), VMF(4) ); return 0; case CG_SETUSERCMDANGLES: CL_SetUserCmdAngles( VMF(1), VMF(2), VMF(3) ); return 0; case COM_SETORGANGLES: Com_SetOrgAngles((float *)VMA(1),(float *)VMA(2)); return 0; /* Ghoul2 Insert Start */ case CG_G2_LISTSURFACES: re.G2API_ListSurfaces( (CGhoul2Info *) VMA(1) ); return 0; case CG_G2_LISTBONES: re.G2API_ListBones( (CGhoul2Info *) VMA(1), args[2]); return 0; case CG_G2_HAVEWEGHOULMODELS: return re.G2API_HaveWeGhoul2Models( *((CGhoul2Info_v *)VMA(1)) ); case CG_G2_SETMODELS: re.G2API_SetGhoul2ModelIndexes( *((CGhoul2Info_v *)VMA(1)),(qhandle_t *)VMA(2),(qhandle_t *)VMA(3)); return 0; /* Ghoul2 Insert End */ case CG_R_GET_LIGHT_STYLE: re.GetLightStyle(args[1], (byte*) VMA(2) ); return 0; case CG_R_SET_LIGHT_STYLE: re.SetLightStyle(args[1], args[2] ); return 0; case CG_R_GET_BMODEL_VERTS: re.GetBModelVerts( args[1], (float (*)[3])VMA(2), (float *)VMA(3) ); return 0; case CG_R_WORLD_EFFECT_COMMAND: re.WorldEffectCommand( (const char *) VMA(1) ); return 0; case CG_CIN_PLAYCINEMATIC: return CIN_PlayCinematic( (const char *) VMA(1), args[2], args[3], args[4], args[5], args[6], (const char *) VMA(7)); case CG_CIN_STOPCINEMATIC: return CIN_StopCinematic(args[1]); case CG_CIN_RUNCINEMATIC: return CIN_RunCinematic(args[1]); case CG_CIN_DRAWCINEMATIC: CIN_DrawCinematic(args[1]); return 0; case CG_CIN_SETEXTENTS: CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]); return 0; case CG_Z_MALLOC: return (intptr_t)Z_Malloc(args[1], (memtag_t) args[2], qfalse); case CG_Z_FREE: Z_Free((void *) VMA(1)); return 0; case CG_UI_SETACTIVE_MENU: UI_SetActiveMenu((const char *) VMA(1),NULL); return 0; case CG_UI_MENU_OPENBYNAME: Menus_OpenByName((const char *) VMA(1)); return 0; case CG_UI_MENU_RESET: Menu_Reset(); return 0; case CG_UI_MENU_NEW: Menu_New((char *) VMA(1)); return 0; case CG_UI_PARSE_INT: PC_ParseInt((int *) VMA(1)); return 0; case CG_UI_PARSE_STRING: PC_ParseString((const char **) VMA(1)); return 0; case CG_UI_PARSE_FLOAT: PC_ParseFloat((float *) VMA(1)); return 0; case CG_UI_STARTPARSESESSION: return(PC_StartParseSession((char *) VMA(1),(char **) VMA(2))); case CG_UI_ENDPARSESESSION: PC_EndParseSession((char *) VMA(1)); return 0; case CG_UI_PARSEEXT: char **holdPtr; holdPtr = (char **) VMA(1); if(!holdPtr) { Com_Error(ERR_FATAL, "CG_UI_PARSEEXT: NULL holdPtr"); } *holdPtr = PC_ParseExt(); return 0; case CG_UI_MENUCLOSE_ALL: Menus_CloseAll(); return 0; case CG_UI_MENUPAINT_ALL: Menu_PaintAll(); return 0; case CG_OPENJK_MENU_PAINT: Menu_Paint( (menuDef_t *)VMA(1), (intptr_t)VMA(2) ); return 0; case CG_OPENJK_GETMENU_BYNAME: return (intptr_t)Menus_FindByName( (const char *)VMA(1) ); case CG_UI_STRING_INIT: String_Init(); return 0; case CG_UI_GETMENUINFO: menuDef_t *menu; int *xPos,*yPos,*w,*h,result; #ifndef __NO_JK2 if(com_jk2 && !com_jk2->integer) { #endif menu = Menus_FindByName((char *) VMA(1)); // Get menu if (menu) { xPos = (int *) VMA(2); *xPos = (int) menu->window.rect.x; yPos = (int *) VMA(3); *yPos = (int) menu->window.rect.y; w = (int *) VMA(4); *w = (int) menu->window.rect.w; h = (int *) VMA(5); *h = (int) menu->window.rect.h; result = qtrue; } else { result = qfalse; } return result; #ifndef __NO_JK2 } else { menu = Menus_FindByName((char *) VMA(1)); // Get menu if (menu) { xPos = (int *) VMA(2); *xPos = (int) menu->window.rect.x; yPos = (int *) VMA(3); *yPos = (int) menu->window.rect.y; result = qtrue; } else { result = qfalse; } return result; } #endif break; case CG_UI_GETITEMTEXT: itemDef_t *item; menu = Menus_FindByName((char *) VMA(1)); // Get menu if (menu) { item = (itemDef_s *) Menu_FindItemByName((menuDef_t *) menu, (char *) VMA(2)); if (item) { Q_strncpyz( (char *) VMA(3), item->text, 256 ); result = qtrue; } else { result = qfalse; } } else { result = qfalse; } return result; case CG_UI_GETITEMINFO: menu = Menus_FindByName((char *) VMA(1)); // Get menu if (menu) { qhandle_t *background; item = (itemDef_s *) Menu_FindItemByName((menuDef_t *) menu, (char *) VMA(2)); if (item) { xPos = (int *) VMA(3); *xPos = (int) item->window.rect.x; yPos = (int *) VMA(4); *yPos = (int) item->window.rect.y; w = (int *) VMA(5); *w = (int) item->window.rect.w; h = (int *) VMA(6); *h = (int) item->window.rect.h; vec4_t *color; color = (vec4_t *) VMA(7); if (!color) { return qfalse; } (*color)[0] = (float) item->window.foreColor[0]; (*color)[1] = (float) item->window.foreColor[1]; (*color)[2] = (float) item->window.foreColor[2]; (*color)[3] = (float) item->window.foreColor[3]; background = (qhandle_t *) VMA(8); if (!background) { return qfalse; } *background = item->window.background; result = qtrue; } else { result = qfalse; } } else { result = qfalse; } return result; case CG_SP_GETSTRINGTEXTSTRING: #ifndef __NO_JK2 case CG_SP_GETSTRINGTEXT: if(com_jk2 && com_jk2->integer) { const char* text; assert(VMA(1)); // assert(VMA(2)); // can now pass in NULL to just query the size if (args[0] == CG_SP_GETSTRINGTEXT) { text = JK2SP_GetStringText( args[1] ); } else { text = JK2SP_GetStringTextString( (const char *) VMA(1) ); } if (VMA(2)) // only if dest buffer supplied... { if ( text[0] ) { Q_strncpyz( (char *) VMA(2), text, args[3] ); } else { Q_strncpyz( (char *) VMA(2), "??", args[3] ); } } return strlen(text); } else { #endif const char* text; assert(VMA(1)); text = SE_GetString( (const char *) VMA(1) ); if (VMA(2)) // only if dest buffer supplied... { if ( text[0] ) { Q_strncpyz( (char *) VMA(2), text, args[3] ); } else { Com_sprintf( (char *) VMA(2), args[3], "??%s", VMA(1) ); } } return strlen(text); #ifndef __NO_JK2 } //break; case CG_SP_REGISTER: return JK2SP_Register( (const char *) VMA(1), args[2]?(SP_REGISTER_MENU|SP_REGISTER_REQUIRED):SP_REGISTER_CLIENT ); #endif default: Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] ); } return 0; }
/* ===================== CL_ParseDownload A download message has been received from the server ===================== */ void CL_ParseDownload( msg_t *msg ) { int size; unsigned char data[ MAX_MSGLEN ]; int block; if ( !*cls.downloadTempName ) { Com_Printf("%s", _( "Server sending download, but no download was requested\n" )); CL_AddReliableCommand( "stopdl" ); return; } // read the data block = MSG_ReadShort( msg ); // TTimo - www dl // if we haven't acked the download redirect yet if ( block == -1 ) { if ( !clc.bWWWDl ) { // server is sending us a www download Q_strncpyz( cls.originalDownloadName, cls.downloadName, sizeof( cls.originalDownloadName ) ); Q_strncpyz( cls.downloadName, MSG_ReadString( msg ), sizeof( cls.downloadName ) ); clc.downloadSize = MSG_ReadLong( msg ); clc.downloadFlags = MSG_ReadLong( msg ); Cvar_SetValue( "cl_downloadSize", clc.downloadSize ); Com_DPrintf( "Server redirected download: %s\n", cls.downloadName ); clc.bWWWDl = qtrue; // activate wwwdl client loop CL_AddReliableCommand( "wwwdl ack" ); // make sure the server is not trying to redirect us again on a bad checksum if ( strstr( clc.badChecksumList, va( "@%s", cls.originalDownloadName ) ) ) { Com_Printf(_( "refusing redirect to %s by server (bad checksum)\n"), cls.downloadName ); CL_AddReliableCommand( "wwwdl fail" ); clc.bWWWDlAborting = qtrue; return; } // make downloadTempName an OS path Q_strncpyz( cls.downloadTempName, FS_BuildOSPath( Cvar_VariableString( "fs_homepath" ), cls.downloadTempName, "" ), sizeof( cls.downloadTempName ) ); cls.downloadTempName[ strlen( cls.downloadTempName ) - 1 ] = '\0'; if ( !DL_BeginDownload( cls.downloadTempName, cls.downloadName, com_developer->integer ) ) { // setting bWWWDl to false after sending the wwwdl fail doesn't work // not sure why, but I suspect we have to eat all remaining block -1 that the server has sent us // still leave a flag so that CL_WWWDownload is inactive // we count on server sending us a gamestate to start up clean again CL_AddReliableCommand( "wwwdl fail" ); clc.bWWWDlAborting = qtrue; Com_Printf(_( "Failed to initialize download for '%s'\n"), cls.downloadName ); } // Check for a disconnected download // we'll let the server disconnect us when it gets the bbl8r message if ( clc.downloadFlags & ( 1 << DL_FLAG_DISCON ) ) { CL_AddReliableCommand( "wwwdl bbl8r" ); cls.bWWWDlDisconnected = qtrue; } return; } else { // server keeps sending that message till we ack it, eat and ignore //MSG_ReadLong( msg ); MSG_ReadString( msg ); MSG_ReadLong( msg ); MSG_ReadLong( msg ); return; } } if ( !block ) { // block zero is special, contains file size clc.downloadSize = MSG_ReadLong( msg ); Cvar_SetValue( "cl_downloadSize", clc.downloadSize ); if ( clc.downloadSize < 0 ) { Com_Error( ERR_DROP, "%s", MSG_ReadString( msg ) ); } } size = MSG_ReadShort( msg ); if ( size < 0 || size > sizeof( data ) ) { Com_Error( ERR_DROP, "CL_ParseDownload: Invalid size %d for download chunk.", size ); } MSG_ReadData( msg, data, size ); if ( clc.downloadBlock != block ) { Com_DPrintf( "CL_ParseDownload: Expected block %d, got %d\n", clc.downloadBlock, block ); return; } // open the file if not opened yet if ( !clc.download ) { clc.download = FS_SV_FOpenFileWrite( cls.downloadTempName ); if ( !clc.download ) { Com_Printf(_( "Could not create %s\n"), cls.downloadTempName ); CL_AddReliableCommand( "stopdl" ); CL_NextDownload(); return; } } if ( size ) { FS_Write( data, size, clc.download ); } CL_AddReliableCommand( va( "nextdl %d", clc.downloadBlock ) ); clc.downloadBlock++; clc.downloadCount += size; // So UI gets access to it Cvar_SetValue( "cl_downloadCount", clc.downloadCount ); if ( !size ) { // A zero length block means EOF if ( clc.download ) { FS_FCloseFile( clc.download ); clc.download = 0; // rename the file FS_SV_Rename( cls.downloadTempName, cls.downloadName ); } *cls.downloadTempName = *cls.downloadName = 0; Cvar_Set( "cl_downloadName", "" ); // send intentions now // We need this because without it, we would hold the last nextdl and then start // loading right away. If we take a while to load, the server is happily trying // to send us that last block over and over. // Write it twice to help make sure we acknowledge the download CL_WritePacket(); CL_WritePacket(); // get another file if needed CL_NextDownload(); } }
/* * CL_InitDownload_f * * Hanldles server's initdownload message, starts web or server download if possible */ static void CL_InitDownload_f( void ) { const char *filename; const char *url; int size, alloc_size; unsigned checksum; qboolean allow_localhttpdownload; download_list_t *dl; // ignore download commands coming from demo files if( cls.demo.playing ) return; // read the data filename = Cmd_Argv( 1 ); size = atoi( Cmd_Argv( 2 ) ); checksum = strtoul( Cmd_Argv( 3 ), NULL, 10 ); allow_localhttpdownload = ( atoi( Cmd_Argv( 4 ) ) != 0 ) && cls.httpbaseurl != NULL; url = Cmd_Argv( 5 ); if( !cls.download.requestname ) { Com_Printf( "Got init download message without request\n" ); return; } if( cls.download.filenum || cls.download.web ) { Com_Printf( "Got init download message while already downloading\n" ); return; } if( size == -1 ) { // means that download was refused Com_Printf( "Server refused download request: %s\n", url ); // if it's refused, url field holds the reason CL_DownloadDone(); return; } if( size <= 0 ) { Com_Printf( "Server gave invalid size, not downloading\n" ); CL_DownloadDone(); return; } if( checksum == 0 ) { Com_Printf( "Server didn't provide checksum, not downloading\n" ); CL_DownloadDone(); return; } if( !COM_ValidateRelativeFilename( filename ) ) { Com_Printf( "Not downloading, invalid filename: %s\n", filename ); CL_DownloadDone(); return; } if( FS_CheckPakExtension( filename ) && !cls.download.requestpak ) { Com_Printf( "Got a pak file when requesting normal one, not downloading\n" ); CL_DownloadDone(); return; } if( !FS_CheckPakExtension( filename ) && cls.download.requestpak ) { Com_Printf( "Got a non pak file when requesting pak, not downloading\n" ); CL_DownloadDone(); return; } if( !strchr( filename, '/' ) ) { Com_Printf( "Refusing to download file with no gamedir: %s\n", filename ); CL_DownloadDone(); return; } // check that it is in game or basegame dir if( strlen( filename ) < strlen( FS_GameDirectory() )+1 || strncmp( filename, FS_GameDirectory(), strlen( FS_GameDirectory() ) ) || filename[strlen( FS_GameDirectory() )] != '/' ) { if( strlen( filename ) < strlen( FS_BaseGameDirectory() )+1 || strncmp( filename, FS_BaseGameDirectory(), strlen( FS_BaseGameDirectory() ) ) || filename[strlen( FS_BaseGameDirectory() )] != '/' ) { Com_Printf( "Can't download, invalid game directory: %s\n", filename ); CL_DownloadDone(); return; } } if( FS_CheckPakExtension( filename ) ) { if( strchr( strchr( filename, '/' ) + 1, '/' ) ) { Com_Printf( "Refusing to download pack file to subdirectory: %s\n", filename ); CL_DownloadDone(); return; } if( !Q_strnicmp( COM_FileBase( filename ), "modules", strlen( "modules" ) ) ) { if( !CL_CanDownloadModules() ) { CL_DownloadDone(); return; } } if( FS_FOpenBaseFile( filename, NULL, FS_READ ) != -1 ) { Com_Printf( "Can't download, file already exists: %s\n", filename ); CL_DownloadDone(); return; } } else { if( strcmp( cls.download.requestname, strchr( filename, '/' ) + 1 ) ) { Com_Printf( "Can't download, got different file than requested: %s\n", filename ); CL_DownloadDone(); return; } } if( cls.download.requestnext ) { dl = cls.download.list; while( dl != NULL ) { if( !Q_stricmp( dl->filename, filename ) ) { Com_Printf( "Skipping, already tried downloading: %s\n", filename ); CL_DownloadDone(); return; } dl = dl->next; } } cls.download.name = ZoneCopyString( filename ); alloc_size = strlen( filename ) + strlen( ".tmp" ) + 1; cls.download.tempname = Mem_ZoneMalloc( alloc_size ); Q_snprintfz( cls.download.tempname, alloc_size, "%s.tmp", filename ); cls.download.web = qfalse; cls.download.cancelled = qfalse; cls.download.disconnect = qfalse; cls.download.size = size; cls.download.checksum = checksum; cls.download.percent = 0; cls.download.timeout = 0; cls.download.retries = 0; cls.download.timestart = Sys_Milliseconds(); cls.download.offset = 0; cls.download.baseoffset = 0; cls.download.pending_reconnect = qfalse; Cvar_ForceSet( "cl_download_name", COM_FileBase( cls.download.name ) ); Cvar_ForceSet( "cl_download_percent", "0" ); if( cls.download.requestnext ) { dl = Mem_ZoneMalloc( sizeof( download_list_t ) ); dl->filename = ZoneCopyString( cls.download.name ); dl->next = cls.download.list; cls.download.list = dl; } if( cl_downloads_from_web->integer && allow_localhttpdownload && url && url[0] != 0 ) { cls.download.web = qtrue; Com_Printf( "Web download: %s from %s%s\n", cls.download.tempname, cls.httpbaseurl, url ); } else if( cl_downloads_from_web->integer && url && url[0] != 0 ) { cls.download.web = qtrue; Com_Printf( "Web download: %s from %s\n", cls.download.tempname, url ); } else { Com_Printf( "Server download: %s\n", cls.download.tempname ); } cls.download.baseoffset = cls.download.offset = FS_FOpenBaseFile( cls.download.tempname, &cls.download.filenum, FS_APPEND ); if( !cls.download.filenum ) { Com_Printf( "Can't download, couldn't open %s for writing\n", cls.download.tempname ); Mem_ZoneFree( cls.download.name ); cls.download.name = NULL; Mem_ZoneFree( cls.download.tempname ); cls.download.tempname = NULL; cls.download.filenum = 0; cls.download.offset = 0; cls.download.size = 0; CL_DownloadDone(); return; } if( cls.download.web ) { char *referer, *fullurl; const char *headers[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; alloc_size = strlen( APP_URI_SCHEME ) + strlen( NET_AddressToString( &cls.serveraddress ) ) + 1; referer = Mem_ZoneMalloc( alloc_size ); Q_snprintfz( referer, alloc_size, APP_URI_SCHEME "%s", NET_AddressToString( &cls.serveraddress ) ); Q_strlwr( referer ); if( allow_localhttpdownload ) { alloc_size = strlen( cls.httpbaseurl ) + 1 + strlen( url ) + 1; fullurl = Mem_ZoneMalloc( alloc_size ); Q_snprintfz( fullurl, alloc_size, "%s/%s", cls.httpbaseurl, url ); } else { size_t url_len = strlen( url ); alloc_size = url_len + 1 + strlen( filename ) * 3 + 1; fullurl = Mem_ZoneMalloc( alloc_size ); Q_snprintfz( fullurl, alloc_size, "%s/", url ); Q_urlencode_unsafechars( filename, fullurl + url_len + 1, alloc_size - url_len - 1 ); } headers[0] = "Referer"; headers[1] = referer; CL_AddSessionHttpRequestHeaders( fullurl, &headers[2] ); CL_AsyncStreamRequest( fullurl, headers, cl_downloads_from_web_timeout->integer / 100, cls.download.offset, CL_WebDownloadReadCb, CL_WebDownloadDoneCb, NULL, NULL, qfalse ); Mem_ZoneFree( fullurl ); Mem_ZoneFree( referer ); return; } // have to use Sys_Milliseconds because cls.realtime might be old from Web_Get cls.download.timeout = Sys_Milliseconds() + 3000; cls.download.retries = 0; CL_AddReliableCommand( va( "nextdl \"%s\" %i", cls.download.name, cls.download.offset ) ); }
/* ================= CG_DrawTourneyScoreboard Draw the oversize scoreboard for tournements ================= */ void CG_DrawOldTourneyScoreboard( void ) { const char *s; vec4_t color; int min, tens, ones; clientInfo_t *ci; int y; int i; // request more scores regularly if ( cg.scoresRequestTime + 2000 < cg.time ) { cg.scoresRequestTime = cg.time; CL_AddReliableCommand( "score" ); } color[0] = 1; color[1] = 1; color[2] = 1; color[3] = 1; // draw the dialog background color[0] = color[1] = color[2] = 0; color[3] = 1; CG_FillRect( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, color ); // print the mesage of the day s = CG_ConfigString( CS_MOTD ); if ( !s[0] ) { s = "Scoreboard"; } // print optional title CG_CenterGiantLine( 8, s ); // print server time ones = cg.time / 1000; min = ones / 60; ones %= 60; tens = ones / 10; ones %= 10; s = va("%i:%i%i", min, tens, ones ); CG_CenterGiantLine( 64, s ); // print the two scores y = 160; if ( cgs.gametype >= GT_TEAM ) { // // teamplay scoreboard // CG_DrawStringExt( 8, y, "Red Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 ); s = va("%i", cg.teamScores[0] ); CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 ); y += 64; CG_DrawStringExt( 8, y, "Blue Team", color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 ); s = va("%i", cg.teamScores[1] ); CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 ); } else { // // free for all scoreboard // for ( i = 0 ; i < MAX_CLIENTS ; i++ ) { ci = &cgs.clientinfo[i]; if ( !ci->infoValid ) { continue; } if ( ci->team != TEAM_FREE ) { continue; } CG_DrawStringExt( 8, y, ci->name, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 ); s = va("%i", ci->score ); CG_DrawStringExt( 632 - GIANT_WIDTH * strlen(s), y, s, color, qtrue, qtrue, GIANT_WIDTH, GIANT_HEIGHT, 0 ); y += 64; } } }
/* * CL_ParseDownload * Handles download message from the server. * Writes data to the file and requests next download block. */ static void CL_ParseDownload( msg_t *msg ) { size_t size, offset; char *svFilename; // read the data svFilename = MSG_ReadString( msg ); offset = MSG_ReadLong( msg ); size = MSG_ReadLong( msg ); if( msg->readcount + size > msg->cursize ) { Com_Printf( "Error: Download message didn't have as much data as it promised\n" ); CL_RetryDownload(); return; } if( !cls.download.filenum ) { Com_Printf( "Error: Download message while not dowloading\n" ); msg->readcount += size; return; } if( Q_stricmp( cls.download.name, svFilename ) ) { Com_Printf( "Error: Download message for wrong file\n" ); msg->readcount += size; return; } if( offset+size > cls.download.size ) { Com_Printf( "Error: Invalid download message\n" ); msg->readcount += size; CL_RetryDownload(); return; } if( cls.download.offset != offset ) { Com_Printf( "Error: Download message for wrong position\n" ); msg->readcount += size; CL_RetryDownload(); return; } FS_Write( msg->data + msg->readcount, size, cls.download.filenum ); msg->readcount += size; cls.download.offset += size; cls.download.percent = (double)cls.download.offset / (double)cls.download.size; clamp( cls.download.percent, 0, 1 ); Cvar_ForceSet( "cl_download_percent", va( "%.1f", cls.download.percent * 100 ) ); if( cls.download.offset < cls.download.size ) { cls.download.timeout = Sys_Milliseconds() + 3000; cls.download.retries = 0; CL_AddReliableCommand( va( "nextdl \"%s\" %i", cls.download.name, cls.download.offset ) ); } else { Com_Printf( "Download complete: %s\n", cls.download.name ); CL_DownloadComplete(); // let the server know we're done CL_AddReliableCommand( va( "nextdl \"%s\" %i", cls.download.name, -1 ) ); CL_StopServerDownload(); CL_DownloadDone(); } }
static void CL_AddReliableCommand2( const char *cmd ) { CL_AddReliableCommand( cmd, qfalse ); }
static void CLQW_ParseDownload( QMsg& message ) { // read the data int size = message.ReadShort(); int percent = message.ReadByte(); if ( clc.demoplaying ) { if ( size > 0 ) { message.readcount += size; } return; // not in demo playback } if ( size == -1 ) { common->Printf( "File not found.\n" ); if ( clc.download ) { common->Printf( "cls.download shouldn't have been set\n" ); FS_FCloseFile( clc.download ); clc.download = 0; } CLQW_RequestNextDownload(); return; } // open the file if not opened yet if ( !clc.download ) { if ( String::NCmp( clc.downloadTempName, "skins/", 6 ) ) { clc.download = FS_FOpenFileWrite( clc.downloadTempName ); } else { char name[ 1024 ]; sprintf( name, "qw/%s", clc.downloadTempName ); clc.download = FS_SV_FOpenFileWrite( name ); } if ( !clc.download ) { message.readcount += size; common->Printf( "Failed to open %s\n", clc.downloadTempName ); CLQW_RequestNextDownload(); return; } } FS_Write( message._data + message.readcount, size, clc.download ); message.readcount += size; if ( percent != 100 ) { // change display routines by zoid // request next block clc.downloadPercent = percent; CL_AddReliableCommand( "nextdl" ); } else { FS_FCloseFile( clc.download ); // rename the temp file to it's final name if ( String::Cmp( clc.downloadTempName, clc.downloadName ) ) { if ( String::NCmp( clc.downloadTempName,"skins/",6 ) ) { FS_Rename( clc.downloadTempName, clc.downloadName ); } else { char oldn[ MAX_OSPATH ]; sprintf( oldn, "qw/%s", clc.downloadTempName ); char newn[ MAX_OSPATH ]; sprintf( newn, "qw/%s", clc.downloadName ); FS_SV_Rename( oldn, newn ); } } clc.download = 0; clc.downloadPercent = 0; // get another file if needed CLQW_RequestNextDownload(); } }
/* ==================== CL_CgameSystemCalls The cgame module is making a system call ==================== */ intptr_t CL_CgameSystemCalls( intptr_t *args ) { switch( args[0] ) { case CG_PRINT: Com_Printf( "%s", (const char*)VMA(1) ); return 0; case CG_ERROR: Com_Error( ERR_DROP, "%s", (const char*)VMA(1) ); return 0; case CG_MILLISECONDS: return Sys_Milliseconds(); case CG_CVAR_REGISTER: Cvar_Register( VMA(1), VMA(2), VMA(3), args[4] ); return 0; case CG_CVAR_UPDATE: Cvar_Update( VMA(1) ); return 0; case CG_CVAR_SET: Cvar_Set( VMA(1), VMA(2) ); return 0; case CG_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer( VMA(1), VMA(2), args[3] ); return 0; case CG_ARGC: return Cmd_Argc(); case CG_ARGV: Cmd_ArgvBuffer( args[1], VMA(2), args[3] ); return 0; case CG_ARGS: Cmd_ArgsBuffer( VMA(1), args[2] ); return 0; case CG_FS_FOPENFILE: return FS_FOpenFileByMode( VMA(1), VMA(2), args[3] ); case CG_FS_READ: FS_Read2( VMA(1), args[2], args[3] ); return 0; case CG_FS_WRITE: FS_Write( VMA(1), args[2], args[3] ); return 0; case CG_FS_FCLOSEFILE: FS_FCloseFile( args[1] ); return 0; case CG_FS_SEEK: return FS_Seek( args[1], args[2], args[3] ); case CG_SENDCONSOLECOMMAND: Cbuf_AddText( VMA(1) ); return 0; case CG_ADDCOMMAND: CL_AddCgameCommand( VMA(1) ); return 0; case CG_REMOVECOMMAND: Cmd_RemoveCommand( VMA(1) ); return 0; case CG_SENDCLIENTCOMMAND: CL_AddReliableCommand( VMA(1) ); return 0; case CG_UPDATESCREEN: // this is used during lengthy level loading, so pump message loop // Com_EventLoop(); // FIXME: if a server restarts here, BAD THINGS HAPPEN! // We can't call Com_EventLoop here, a restart will crash and this _does_ happen // if there is a map change while we are downloading at pk3. // ZOID SCR_UpdateScreen(); return 0; case CG_CM_LOADMAP: CL_CM_LoadMap( VMA(1) ); return 0; case CG_CM_NUMINLINEMODELS: return CM_NumInlineModels(); case CG_CM_INLINEMODEL: return CM_InlineModel( args[1] ); case CG_CM_TEMPBOXMODEL: return CM_TempBoxModel( VMA(1), VMA(2), /*int capsule*/ qfalse ); case CG_CM_TEMPCAPSULEMODEL: return CM_TempBoxModel( VMA(1), VMA(2), /*int capsule*/ qtrue ); case CG_CM_POINTCONTENTS: return CM_PointContents( VMA(1), args[2] ); case CG_CM_TRANSFORMEDPOINTCONTENTS: return CM_TransformedPointContents( VMA(1), args[2], VMA(3), VMA(4) ); case CG_CM_BOXTRACE: CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qfalse ); return 0; case CG_CM_CAPSULETRACE: CM_BoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], /*int capsule*/ qtrue ); return 0; case CG_CM_TRANSFORMEDBOXTRACE: CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qfalse ); return 0; case CG_CM_TRANSFORMEDCAPSULETRACE: CM_TransformedBoxTrace( VMA(1), VMA(2), VMA(3), VMA(4), VMA(5), args[6], args[7], VMA(8), VMA(9), /*int capsule*/ qtrue ); return 0; case CG_CM_MARKFRAGMENTS: return re.MarkFragments( args[1], VMA(2), VMA(3), args[4], VMA(5), args[6], VMA(7) ); case CG_S_STARTSOUND: S_StartSound( VMA(1), args[2], args[3], args[4] ); return 0; case CG_S_STARTLOCALSOUND: S_StartLocalSound( args[1], args[2] ); return 0; case CG_S_CLEARLOOPINGSOUNDS: S_ClearLoopingSounds(args[1]); return 0; case CG_S_ADDLOOPINGSOUND: S_AddLoopingSound( args[1], VMA(2), VMA(3), args[4] ); return 0; case CG_S_ADDREALLOOPINGSOUND: S_AddRealLoopingSound( args[1], VMA(2), VMA(3), args[4] ); return 0; case CG_S_STOPLOOPINGSOUND: S_StopLoopingSound( args[1] ); return 0; case CG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition( args[1], VMA(2) ); return 0; case CG_S_RESPATIALIZE: S_Respatialize( args[1], VMA(2), VMA(3), args[4] ); return 0; case CG_S_REGISTERSOUND: return S_RegisterSound( VMA(1), args[2] ); case CG_S_STARTBACKGROUNDTRACK: S_StartBackgroundTrack( VMA(1), VMA(2) ); return 0; case CG_R_LOADWORLDMAP: re.LoadWorld( VMA(1) ); return 0; case CG_R_REGISTERMODEL: return re.RegisterModel( VMA(1) ); case CG_R_REGISTERSKIN: return re.RegisterSkin( VMA(1) ); case CG_R_REGISTERSHADER: return re.RegisterShader( VMA(1) ); case CG_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip( VMA(1) ); case CG_R_REGISTERFONT: re.RegisterFont( VMA(1), args[2], VMA(3)); case CG_R_CLEARSCENE: re.ClearScene(); return 0; case CG_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene( VMA(1) ); return 0; case CG_R_ADDPOLYTOSCENE: re.AddPolyToScene( args[1], args[2], VMA(3), 1 ); return 0; case CG_R_ADDPOLYSTOSCENE: re.AddPolyToScene( args[1], args[2], VMA(3), args[4] ); return 0; case CG_R_LIGHTFORPOINT: return re.LightForPoint( VMA(1), VMA(2), VMA(3), VMA(4) ); case CG_R_ADDLIGHTTOSCENE: re.AddLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); return 0; case CG_R_ADDADDITIVELIGHTTOSCENE: re.AddAdditiveLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); return 0; case CG_R_RENDERSCENE: re.RenderScene( VMA(1) ); return 0; case CG_R_SETCOLOR: re.SetColor( VMA(1) ); return 0; case CG_R_DRAWSTRETCHPIC: re.DrawStretchPic( VMF(1), VMF(2), VMF(3), VMF(4), VMF(5), VMF(6), VMF(7), VMF(8), args[9] ); return 0; case CG_R_MODELBOUNDS: re.ModelBounds( args[1], VMA(2), VMA(3) ); return 0; case CG_R_LERPTAG: return re.LerpTag( VMA(1), args[2], args[3], args[4], VMF(5), VMA(6) ); case CG_GETGLCONFIG: CL_GetGlconfig( VMA(1) ); return 0; case CG_GETGAMESTATE: CL_GetGameState( VMA(1) ); return 0; case CG_GETCURRENTSNAPSHOTNUMBER: CL_GetCurrentSnapshotNumber( VMA(1), VMA(2) ); return 0; case CG_GETSNAPSHOT: return CL_GetSnapshot( args[1], VMA(2) ); case CG_GETSERVERCOMMAND: return CL_GetServerCommand( args[1] ); case CG_GETCURRENTCMDNUMBER: return CL_GetCurrentCmdNumber(); case CG_GETUSERCMD: return CL_GetUserCmd( args[1], VMA(2) ); case CG_SETUSERCMDVALUE: CL_SetUserCmdValue( args[1], VMF(2) ); return 0; case CG_MEMORY_REMAINING: return Hunk_MemoryRemaining(); case CG_KEY_ISDOWN: return Key_IsDown( args[1] ); case CG_KEY_GETCATCHER: return Key_GetCatcher(); case CG_KEY_SETCATCHER: // Don't allow the cgame module to close the console Key_SetCatcher( args[1] | ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ); return 0; case CG_KEY_GETKEY: return Key_GetKey( VMA(1) ); case CG_MEMSET: Com_Memset( VMA(1), args[2], args[3] ); return 0; case CG_MEMCPY: Com_Memcpy( VMA(1), VMA(2), args[3] ); return 0; case CG_STRNCPY: strncpy( VMA(1), VMA(2), args[3] ); return args[1]; case CG_SIN: return FloatAsInt( sin( VMF(1) ) ); case CG_COS: return FloatAsInt( cos( VMF(1) ) ); case CG_ATAN2: return FloatAsInt( atan2( VMF(1), VMF(2) ) ); case CG_SQRT: return FloatAsInt( sqrt( VMF(1) ) ); case CG_FLOOR: return FloatAsInt( floor( VMF(1) ) ); case CG_CEIL: return FloatAsInt( ceil( VMF(1) ) ); case CG_ACOS: return FloatAsInt( Q_acos( VMF(1) ) ); case CG_PC_ADD_GLOBAL_DEFINE: return botlib_export->PC_AddGlobalDefine( VMA(1) ); case CG_PC_LOAD_SOURCE: return botlib_export->PC_LoadSourceHandle( VMA(1) ); case CG_PC_FREE_SOURCE: return botlib_export->PC_FreeSourceHandle( args[1] ); case CG_PC_READ_TOKEN: return botlib_export->PC_ReadTokenHandle( args[1], VMA(2) ); case CG_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine( args[1], VMA(2), VMA(3) ); case CG_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case CG_REAL_TIME: return Com_RealTime( VMA(1) ); case CG_SNAPVECTOR: Sys_SnapVector( VMA(1) ); return 0; case CG_CIN_PLAYCINEMATIC: return CIN_PlayCinematic(VMA(1), args[2], args[3], args[4], args[5], args[6]); case CG_CIN_STOPCINEMATIC: return CIN_StopCinematic(args[1]); case CG_CIN_RUNCINEMATIC: return CIN_RunCinematic(args[1]); case CG_CIN_DRAWCINEMATIC: CIN_DrawCinematic(args[1]); return 0; case CG_CIN_SETEXTENTS: CIN_SetExtents(args[1], args[2], args[3], args[4], args[5]); return 0; case CG_R_REMAP_SHADER: re.RemapShader( VMA(1), VMA(2), VMA(3) ); return 0; /* case CG_LOADCAMERA: return loadCamera(VMA(1)); case CG_STARTCAMERA: startCamera(args[1]); return 0; case CG_GETCAMERAINFO: return getCameraInfo(args[1], VMA(2), VMA(3)); */ case CG_GET_ENTITY_TOKEN: return re.GetEntityToken( VMA(1), args[2] ); case CG_R_INPVS: return re.inPVS( VMA(1), VMA(2) ); default: assert(0); Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] ); } return 0; }
/* ==================== CL_CgameSystemCalls The cgame module is making a system call ==================== */ intptr_t CL_CgameSystemCalls( intptr_t *args ) { switch ( args[0] ) { case CG_PRINT: Com_Printf( "%s", (const char*)VMA(1) ); return 0; case CG_ERROR: Com_Error( ERR_DROP, "%s", (const char*)VMA(1) ); return 0; case CG_MILLISECONDS: return Sys_Milliseconds(); case CG_CVAR_REGISTER: Cvar_Register( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[4] ); return 0; case CG_CVAR_UPDATE: Cvar_Update( VMA( 1 ) ); return 0; case CG_CVAR_SET: Cvar_SetSafe( VMA(1), VMA(2) ); return 0; case CG_CVAR_VARIABLESTRINGBUFFER: Cvar_VariableStringBuffer( VMA( 1 ), VMA( 2 ), args[3] ); return 0; case CG_ARGC: return Cmd_Argc(); case CG_ARGV: Cmd_ArgvBuffer( args[1], VMA( 2 ), args[3] ); return 0; case CG_ARGS: Cmd_ArgsBuffer( VMA( 1 ), args[2] ); return 0; case CG_FS_FOPENFILE: return FS_FOpenFileByMode( VMA( 1 ), VMA( 2 ), args[3] ); case CG_FS_READ: FS_Read( VMA( 1 ), args[2], args[3] ); return 0; case CG_FS_WRITE: return FS_Write( VMA( 1 ), args[2], args[3] ); case CG_FS_FCLOSEFILE: FS_FCloseFile( args[1] ); return 0; case CG_SENDCONSOLECOMMAND: Cbuf_AddText( VMA( 1 ) ); return 0; case CG_ADDCOMMAND: CL_AddCgameCommand( VMA( 1 ) ); return 0; case CG_REMOVECOMMAND: Cmd_RemoveCommandSafe( VMA(1) ); return 0; case CG_SENDCLIENTCOMMAND: CL_AddReliableCommand(VMA(1), qfalse); return 0; case CG_UPDATESCREEN: // this is used during lengthy level loading, so pump message loop // Com_EventLoop(); // FIXME: if a server restarts here, BAD THINGS HAPPEN! // We can't call Com_EventLoop here, a restart will crash and this _does_ happen // if there is a map change while we are downloading at pk3. // ZOID SCR_UpdateScreen(); return 0; case CG_CM_LOADMAP: CL_CM_LoadMap( VMA( 1 ) ); return 0; case CG_CM_NUMINLINEMODELS: return CM_NumInlineModels(); case CG_CM_INLINEMODEL: return CM_InlineModel( args[1] ); case CG_CM_TEMPBOXMODEL: return CM_TempBoxModel( VMA( 1 ), VMA( 2 ), qfalse ); case CG_CM_TEMPCAPSULEMODEL: return CM_TempBoxModel( VMA( 1 ), VMA( 2 ), qtrue ); case CG_CM_POINTCONTENTS: return CM_PointContents( VMA( 1 ), args[2] ); case CG_CM_TRANSFORMEDPOINTCONTENTS: return CM_TransformedPointContents( VMA( 1 ), args[2], VMA( 3 ), VMA( 4 ) ); case CG_CM_BOXTRACE: CM_BoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[6], args[7], /*int capsule*/ qfalse ); return 0; case CG_CM_TRANSFORMEDBOXTRACE: CM_TransformedBoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[6], args[7], VMA( 8 ), VMA( 9 ), /*int capsule*/ qfalse ); return 0; case CG_CM_CAPSULETRACE: CM_BoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[6], args[7], /*int capsule*/ qtrue ); return 0; case CG_CM_TRANSFORMEDCAPSULETRACE: CM_TransformedBoxTrace( VMA( 1 ), VMA( 2 ), VMA( 3 ), VMA( 4 ), VMA( 5 ), args[6], args[7], VMA( 8 ), VMA( 9 ), /*int capsule*/ qtrue ); return 0; case CG_CM_MARKFRAGMENTS: return re.MarkFragments( args[1], VMA( 2 ), VMA( 3 ), args[4], VMA( 5 ), args[6], VMA( 7 ) ); case CG_S_STARTSOUND: S_StartSound( VMA( 1 ), args[2], args[3], args[4] ); return 0; //----(SA) added case CG_S_STARTSOUNDEX: S_StartSoundEx( VMA( 1 ), args[2], args[3], args[4], args[5] ); return 0; //----(SA) end case CG_S_STARTLOCALSOUND: S_StartLocalSound( args[1], args[2] ); return 0; case CG_S_CLEARLOOPINGSOUNDS: S_ClearLoopingSounds( args[1] ); // (SA) modified so no_pvs sounds can function return 0; case CG_S_ADDLOOPINGSOUND: // FIXME MrE: handling of looping sounds changed S_AddLoopingSound( args[1], VMA( 2 ), VMA( 3 ), args[4], args[5], args[6] ); return 0; case CG_S_ADDREALLOOPINGSOUND: S_AddLoopingSound( args[1], VMA( 2 ), VMA( 3 ), args[4], args[5], args[6] ); //S_AddRealLoopingSound( args[1], VMA(2), VMA(3), args[4], args[5] ); return 0; case CG_S_STOPLOOPINGSOUND: // RF, not functional anymore, since we reverted to old looping code //S_StopLoopingSound( args[1] ); return 0; case CG_S_UPDATEENTITYPOSITION: S_UpdateEntityPosition( args[1], VMA( 2 ) ); return 0; // Ridah, talking animations case CG_S_GETVOICEAMPLITUDE: return S_GetVoiceAmplitude( args[1] ); // done. case CG_S_RESPATIALIZE: S_Respatialize( args[1], VMA( 2 ), VMA( 3 ), args[4] ); return 0; case CG_S_REGISTERSOUND: return S_RegisterSound( VMA( 1 ), qfalse ); case CG_S_STARTBACKGROUNDTRACK: S_StartBackgroundTrack( VMA( 1 ), VMA( 2 ) ); return 0; case CG_S_STARTSTREAMINGSOUND: S_StartStreamingSound( VMA( 1 ), VMA( 2 ), args[3], args[4], args[5] ); return 0; case CG_R_LOADWORLDMAP: re.LoadWorld( VMA( 1 ) ); return 0; case CG_R_REGISTERMODEL: return re.RegisterModel( VMA( 1 ) ); case CG_R_REGISTERSKIN: return re.RegisterSkin( VMA( 1 ) ); //----(SA) added case CG_R_GETSKINMODEL: return re.GetSkinModel( args[1], VMA( 2 ), VMA( 3 ) ); case CG_R_GETMODELSHADER: return re.GetShaderFromModel( args[1], args[2], args[3] ); //----(SA) end case CG_R_REGISTERSHADER: return re.RegisterShader( VMA( 1 ) ); case CG_R_REGISTERFONT: re.RegisterFont( VMA( 1 ), args[2], VMA( 3 ) ); return 0; case CG_R_REGISTERSHADERNOMIP: return re.RegisterShaderNoMip( VMA( 1 ) ); case CG_R_CLEARSCENE: re.ClearScene(); return 0; case CG_R_ADDREFENTITYTOSCENE: re.AddRefEntityToScene( VMA( 1 ) ); return 0; case CG_R_ADDPOLYTOSCENE: re.AddPolyToScene( args[1], args[2], VMA( 3 ) ); return 0; // Ridah case CG_R_ADDPOLYSTOSCENE: re.AddPolysToScene( args[1], args[2], VMA( 3 ), args[4] ); return 0; // done. // case CG_R_LIGHTFORPOINT: // return re.LightForPoint( VMA(1), VMA(2), VMA(3), VMA(4) ); case CG_R_ADDLIGHTTOSCENE: re.AddLightToScene( VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[6] ); return 0; // case CG_R_ADDADDITIVELIGHTTOSCENE: // re.AddAdditiveLightToScene( VMA(1), VMF(2), VMF(3), VMF(4), VMF(5) ); // return 0; case CG_R_ADDCORONATOSCENE: re.AddCoronaToScene( VMA( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), args[6], args[7] ); return 0; case CG_R_SETFOG: re.SetFog( args[1], args[2], args[3], VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ) ); return 0; case CG_R_RENDERSCENE: re.RenderScene( VMA( 1 ) ); return 0; case CG_R_SETCOLOR: re.SetColor( VMA( 1 ) ); return 0; case CG_R_DRAWSTRETCHPIC: re.DrawStretchPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[9] ); return 0; case CG_R_DRAWROTATEDPIC: re.DrawRotatedPic( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[9], VMF( 10 ) ); return 0; case CG_R_DRAWSTRETCHPIC_GRADIENT: re.DrawStretchPicGradient( VMF( 1 ), VMF( 2 ), VMF( 3 ), VMF( 4 ), VMF( 5 ), VMF( 6 ), VMF( 7 ), VMF( 8 ), args[9], VMA( 10 ), args[11] ); return 0; case CG_R_MODELBOUNDS: re.ModelBounds( args[1], VMA( 2 ), VMA( 3 ) ); return 0; case CG_R_LERPTAG: return re.LerpTag( VMA( 1 ), VMA( 2 ), VMA( 3 ), args[4] ); case CG_GETGLCONFIG: CL_GetGlconfig( VMA( 1 ) ); return 0; case CG_GETGAMESTATE: CL_GetGameState( VMA( 1 ) ); return 0; case CG_GETCURRENTSNAPSHOTNUMBER: CL_GetCurrentSnapshotNumber( VMA( 1 ), VMA( 2 ) ); return 0; case CG_GETSNAPSHOT: return CL_GetSnapshot( args[1], VMA( 2 ) ); case CG_GETSERVERCOMMAND: return CL_GetServerCommand( args[1] ); case CG_GETCURRENTCMDNUMBER: return CL_GetCurrentCmdNumber(); case CG_GETUSERCMD: return CL_GetUserCmd( args[1], VMA( 2 ) ); case CG_SETUSERCMDVALUE: CL_SetUserCmdValue( args[1], args[2], VMF( 3 ), args[4], args[5] ); return 0; case CG_SETCLIENTLERPORIGIN: CL_SetClientLerpOrigin( VMF( 1 ), VMF( 2 ), VMF( 3 ) ); return 0; case CG_MEMORY_REMAINING: return Hunk_MemoryRemaining(); case CG_KEY_ISDOWN: return Key_IsDown( args[1] ); case CG_KEY_GETCATCHER: return Key_GetCatcher(); case CG_KEY_SETCATCHER: // Don't allow the cgame module to close the console Key_SetCatcher( args[1] | ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) ); return 0; case CG_KEY_GETKEY: return Key_GetKey( VMA( 1 ) ); case CG_MEMSET: Com_Memset( VMA(1), args[2], args[3] ); return args[1]; case CG_MEMCPY: Com_Memcpy( VMA(1), VMA(2), args[3] ); return args[1]; case CG_STRNCPY: strncpy( VMA(1), VMA(2), args[3] ); return args[1]; case CG_SIN: return FloatAsInt( sin( VMF( 1 ) ) ); case CG_COS: return FloatAsInt( cos( VMF( 1 ) ) ); case CG_ATAN2: return FloatAsInt( atan2( VMF( 1 ), VMF( 2 ) ) ); case CG_SQRT: return FloatAsInt( sqrt( VMF( 1 ) ) ); case CG_FLOOR: return FloatAsInt( floor( VMF( 1 ) ) ); case CG_CEIL: return FloatAsInt( ceil( VMF( 1 ) ) ); case CG_ACOS: return FloatAsInt( Q_acos( VMF( 1 ) ) ); case CG_PC_ADD_GLOBAL_DEFINE: return botlib_export->PC_AddGlobalDefine( VMA( 1 ) ); case CG_PC_LOAD_SOURCE: return botlib_export->PC_LoadSourceHandle( VMA( 1 ) ); case CG_PC_FREE_SOURCE: return botlib_export->PC_FreeSourceHandle( args[1] ); case CG_PC_READ_TOKEN: return botlib_export->PC_ReadTokenHandle( args[1], VMA( 2 ) ); case CG_PC_SOURCE_FILE_AND_LINE: return botlib_export->PC_SourceFileAndLine( args[1], VMA( 2 ), VMA( 3 ) ); case CG_S_STOPBACKGROUNDTRACK: S_StopBackgroundTrack(); return 0; case CG_REAL_TIME: return Com_RealTime( VMA( 1 ) ); case CG_SNAPVECTOR: Q_SnapVector(VMA(1)); return 0; case CG_SENDMOVESPEEDSTOGAME: SV_SendMoveSpeedsToGame( args[1], VMA( 2 ) ); return 0; case CG_CIN_PLAYCINEMATIC: return CIN_PlayCinematic( VMA( 1 ), args[2], args[3], args[4], args[5], args[6] ); case CG_CIN_STOPCINEMATIC: return CIN_StopCinematic( args[1] ); case CG_CIN_RUNCINEMATIC: return CIN_RunCinematic( args[1] ); case CG_CIN_DRAWCINEMATIC: CIN_DrawCinematic( args[1] ); return 0; case CG_CIN_SETEXTENTS: CIN_SetExtents( args[1], args[2], args[3], args[4], args[5] ); return 0; case CG_R_REMAP_SHADER: re.RemapShader( VMA( 1 ), VMA( 2 ), VMA( 3 ) ); return 0; case CG_TESTPRINTINT: // Com_Printf( "%s%i\n", (const char*)VMA( 1 ), args[2] ); return 0; case CG_TESTPRINTFLOAT: // Com_Printf( "%s%f\n", (const char*)VMA( 1 ), VMF( 2 ) ); return 0; case CG_LOADCAMERA: return loadCamera( args[1], VMA( 2 ) ); case CG_STARTCAMERA: startCamera( args[1], args[2] ); return 0; case CG_GETCAMERAINFO: return getCameraInfo( args[1], args[2], VMA( 3 ), VMA( 4 ), VMA( 5 ) ); case CG_GET_ENTITY_TOKEN: return re.GetEntityToken( VMA( 1 ), args[2] ); case CG_INGAME_POPUP: if ( clc.state == CA_ACTIVE && !clc.demoplaying ) { // NERVE - SMF if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_PICKTEAM" ) ) { VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_PICKTEAM ); } else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_PICKPLAYER" ) ) { VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_PICKPLAYER ); } else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_QUICKMESSAGE" ) ) { VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_QUICKMESSAGE ); } else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_QUICKMESSAGEALT" ) ) { VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_QUICKMESSAGEALT ); } else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_LIMBO" ) ) { VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_LIMBO ); } else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_AUTOUPDATE" ) ) { VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_WM_AUTOUPDATE ); } // -NERVE - SMF else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "hbook1" ) ) { //----(SA) VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_BOOK1 ); } else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "hbook2" ) ) { //----(SA) VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_BOOK2 ); } else if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "hbook3" ) ) { //----(SA) VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_BOOK3 ); } else { VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_CLIPBOARD ); } } return 0; // NERVE - SMF case CG_INGAME_CLOSEPOPUP: // if popup menu is up, then close it if ( VMA( 1 ) && !Q_stricmp( VMA( 1 ), "UIMENU_WM_LIMBO" ) ) { if ( VM_Call( uivm, UI_GET_ACTIVE_MENU ) == UIMENU_WM_LIMBO ) { VM_Call( uivm, UI_KEY_EVENT, K_ESCAPE, qtrue ); VM_Call( uivm, UI_KEY_EVENT, K_ESCAPE, qtrue ); } } return 0; case CG_LIMBOCHAT: if ( VMA( 1 ) ) { CL_AddToLimboChat( VMA( 1 ) ); } return 0; case CG_KEY_GETBINDINGBUF: Key_GetBindingBuf( args[1], VMA( 2 ), args[3] ); return 0; case CG_KEY_SETBINDING: Key_SetBinding( args[1], VMA( 2 ) ); return 0; case CG_KEY_KEYNUMTOSTRINGBUF: Key_KeynumToStringBuf( args[1], VMA( 2 ), args[3] ); return 0; case CG_TRANSLATE_STRING: CL_TranslateString( VMA( 1 ), VMA( 2 ) ); return 0; // - NERVE - SMF default: Com_Error( ERR_DROP, "Bad cgame system trap: %ld", (long int) args[0] ); } return 0; }