/* ================ vmMain This is the only way control passes into the module. This must be the very first function compiled into the .qvm file ================ */ Q_EXPORT intptr_t vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) { switch ( command ) { case UI_GETAPIVERSION: return UI_API_VERSION; case UI_INIT: UI_Init(); return 0; case UI_SHUTDOWN: UI_Shutdown(); return 0; case UI_KEY_EVENT: UI_KeyEvent( arg0, arg1 ); return 0; case UI_MOUSE_EVENT: UI_MouseEvent( arg0, arg1 ); return 0; case UI_REFRESH: UI_Refresh( arg0 ); return 0; case UI_IS_FULLSCREEN: return UI_IsFullscreen(); case UI_SET_ACTIVE_MENU: UI_SetActiveMenu( arg0 ); return 0; case UI_CONSOLE_COMMAND: return UI_ConsoleCommand(arg0); case UI_DRAW_CONNECT_SCREEN: UI_DrawConnectScreen( arg0 ); return 0; /* case UI_HASUNIQUECDKEY: // mod authors need to observe this return qtrue; // change this to qfalse for mods! */ } return -1; }
/* ===================== 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 ) { if ( !com_cl_running || !com_cl_running->integer ) { return; } #ifdef _XBOX Cvar_Set("r_norefresh", "0"); #endif if (cls.uiStarted) UI_SetActiveMenu( NULL,NULL ); SCR_StopCinematic (); S_ClearSoundBuffer(); #ifdef _XBOX // extern qboolean RE_RegisterImages_LevelLoadEnd(void); // RE_RegisterImages_LevelLoadEnd(); R_DeleteTextures(); #endif // 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 (); CL_FreeReliableCommands(); extern void CL_FreeServerCommands(void); CL_FreeServerCommands(); 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 }
/* ================== SCR_Init ================== */ void SCR_Init( void ) { if( scr_init ) return; MsgDev( D_NOTE, "SCR_Init()\n" ); scr_centertime = Cvar_Get( "scr_centertime", "2.5", 0, "centerprint hold time" ); cl_levelshot_name = Cvar_Get( "cl_levelshot_name", "*black", 0, "contains path to current levelshot" ); cl_allow_levelshots = Cvar_Get( "allow_levelshots", "0", CVAR_ARCHIVE, "allow engine to use indivdual levelshots instead of 'loading' image" ); scr_loading = Cvar_Get( "scr_loading", "0", 0, "loading bar progress" ); scr_download = Cvar_Get( "scr_download", "0", 0, "downloading bar progress" ); cl_testlights = Cvar_Get( "cl_testlights", "0", 0, "test dynamic lights" ); cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", CVAR_ARCHIVE, "envshot size of cube side" ); scr_dark = Cvar_Get( "v_dark", "0", 0, "starts level from dark screen" ); scr_viewsize = Cvar_Get( "viewsize", "120", CVAR_ARCHIVE, "screen size" ); // register our commands Cmd_AddCommand( "timerefresh", SCR_TimeRefresh_f, "turn quickly and print rendering statistcs" ); Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" ); Cmd_AddCommand( "viewpos", SCR_Viewpos_f, "prints current player origin" ); Cmd_AddCommand( "sizeup", SCR_SizeUp_f, "screen size up to 10 points" ); Cmd_AddCommand( "sizedown", SCR_SizeDown_f, "screen size down to 10 points" ); if( host.state != HOST_RESTART && !UI_LoadProgs( )) { Msg( "^1Error: ^7can't initialize menu library\n" ); // this is not fatal for us // console still can't be toggled in-game without extra cmd-line switch if( !host.developer ) host.developer = 1; // we need console, because menu is missing } SCR_LoadCreditsFont (); SCR_InstallParticlePalette (); SCR_RegisterTextures (); SCR_InitCinematic(); SCR_VidInit(); if( host.state != HOST_RESTART ) { if( host.developer && Sys_CheckParm( "-toconsole" )) Cbuf_AddText( "toggleconsole\n" ); else UI_SetActiveMenu( true ); } scr_init = true; }
/* ================ vmMain This is the only way control passes into the module. This must be the very first function compiled into the .qvm file ================ */ int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6 ) { switch ( command ) { case UI_GETAPIVERSION: return UI_API_VERSION; case UI_INIT: UI_Init(); return 0; case UI_SHUTDOWN: UI_Shutdown(); return 0; case UI_KEY_EVENT: UI_KeyEvent( arg0 ); return 0; case UI_MOUSE_EVENT: UI_MouseEvent( arg0, arg1 ); return 0; case UI_REFRESH: UI_Refresh( arg0 ); return 0; case UI_IS_FULLSCREEN: return UI_IsFullscreen(); case UI_SET_ACTIVE_MENU: UI_SetActiveMenu( arg0 ); return 0; case UI_CONSOLE_COMMAND: return UI_ConsoleCommand(); case UI_DRAW_CONNECT_SCREEN: UI_DrawConnectScreen( arg0 ); return 0; } return -1; }
/* ================== SCR_PlayCinematic ================== */ qboolean SCR_PlayCinematic( const char *arg ) { string path; const char *fullpath; fullpath = FS_GetDiskPath( arg, false ); if( FS_FileExists( arg, false ) && !fullpath ) { MsgDev( D_ERROR, "Couldn't load %s from packfile. Please extract it\n", path ); return false; } AVI_OpenVideo( cin_state, fullpath, true, true, false ); if( !AVI_IsActive( cin_state )) { AVI_CloseVideo( cin_state ); return false; } if( !( AVI_GetVideoInfo( cin_state, &xres, &yres, &video_duration ))) // couldn't open this at all. { AVI_CloseVideo( cin_state ); return false; } if( AVI_GetAudioInfo( cin_state, &cin_audio )) { // begin streaming S_StopAllSounds(); S_StartStreaming(); } UI_SetActiveMenu( false ); SCR_RebuildGammaTable(); cls.state = ca_cinematic; cin_time = 0.0f; return 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 }
/* ================== SCR_DrawScreenField This will be called twice if rendering in stereo mode ================== */ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) { re.BeginFrame( stereoFrame ); qboolean uiFullscreen = _UI_IsFullscreen(); // wide aspect ratio screens need to have the sides cleared // unless they are displaying game renderings if ( uiFullscreen || (cls.state != CA_ACTIVE && cls.state != CA_CINEMATIC) ) { if ( cls.glconfig.vidWidth * 480 > cls.glconfig.vidHeight * 640 ) { re.SetColor( g_color_table[0] ); re.DrawStretchPic( 0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, 0, 0, 0, 0 ); re.SetColor( NULL ); } } // if the menu is going to cover the entire screen, we // don't need to render anything under it if ( !uiFullscreen ) { switch( cls.state ) { default: Com_Error( ERR_FATAL, "SCR_DrawScreenField: bad cls.state" ); break; case CA_CINEMATIC: SCR_DrawCinematic(); break; case CA_DISCONNECTED: // force menu up UI_SetActiveMenu( "mainMenu",NULL ); // VM_Call( uivm, UI_SET_ACTIVE_MENU, UIMENU_MAIN ); break; case CA_CONNECTING: case CA_CHALLENGING: case CA_CONNECTED: // connecting clients will only show the connection dialog UI_DrawConnect( clc.servername, cls.updateInfoString ); break; case CA_LOADING: case CA_PRIMED: // draw the game information screen and loading progress CL_CGameRendering( stereoFrame ); // also draw the connection information, so it doesn't // flash away too briefly on local or lan games UI_DrawConnectText( clc.servername, cls.updateInfoString ); break; case CA_ACTIVE: if (CL_IsRunningInGameCinematic() || CL_InGameCinematicOnStandBy()) { SCR_DrawCinematic(); } else { CL_CGameRendering( stereoFrame ); } break; } } re.ProcessDissolve(); // draw downloading progress bar // the menu draws next _UI_Refresh( cls.realtime ); // console draws next Con_DrawConsole (); // debug graph can be drawn on top of anything if ( cl_debuggraph->integer || cl_timegraph->integer ) { SCR_DrawDebugGraph (); } }
/* ================= CL_ConnectionlessPacket Responses to broadcasts, etc ================= */ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg ) { char *args; char *c, buf[MAX_SYSPATH]; int len = sizeof( buf ); int dataoffset = 0; netadr_t servadr; BF_Clear( msg ); BF_ReadLong( msg ); // skip the -1 args = BF_ReadStringLine( msg ); Cmd_TokenizeString( args ); c = Cmd_Argv( 0 ); MsgDev( D_NOTE, "CL_ConnectionlessPacket: %s : %s\n", NET_AdrToString( from ), c ); // server connection if( !Q_strcmp( c, "client_connect" )) { if( cls.state == ca_connected ) { MsgDev( D_INFO, "dup connect received. ignored\n"); return; } Netchan_Setup( NS_CLIENT, &cls.netchan, from, net_qport->integer); BF_WriteByte( &cls.netchan.message, clc_stringcmd ); BF_WriteString( &cls.netchan.message, "new" ); cls.state = ca_connected; cl.validsequence = 0; // haven't gotten a valid frame update yet cl.delta_sequence = -1; // we'll request a full delta from the baseline cls.lastoutgoingcommand = -1; // we don't have a backed up cmd history yet cls.nextcmdtime = host.realtime; // we can send a cmd right away CL_StartupDemoHeader (); UI_SetActiveMenu( false ); } else if( !Q_strcmp( c, "info" )) { // server responding to a status broadcast CL_ParseStatusMessage( from, msg ); } else if( !Q_strcmp( c, "netinfo" )) { // server responding to a status broadcast CL_ParseNETInfoMessage( from, msg ); } else if( !Q_strcmp( c, "cmd" )) { // remote command from gui front end if( !NET_IsLocalAddress( from )) { Msg( "Command packet from remote host. Ignored.\n" ); return; } #ifdef XASH_SDL SDL_RestoreWindow( host.hWnd ); #endif args = BF_ReadString( msg ); Cbuf_AddText( args ); Cbuf_AddText( "\n" ); } else if( !Q_strcmp( c, "print" )) { // print command from somewhere Msg("remote: %s\n", BF_ReadString( msg ) ); } else if( !Q_strcmp( c, "ping" )) { // ping from somewhere Netchan_OutOfBandPrint( NS_CLIENT, from, "ack" ); } else if( !Q_strcmp( c, "challenge" )) { // challenge from the server we are connecting to cls.challenge = Q_atoi( Cmd_Argv( 1 )); CL_SendConnectPacket(); return; } else if( !Q_strcmp( c, "echo" )) { // echo request from server Netchan_OutOfBandPrint( NS_CLIENT, from, "%s", Cmd_Argv( 1 )); } else if( !Q_strcmp( c, "disconnect" )) { // a disconnect message from the server, which will happen if the server // dropped the connection but it is still getting packets from us CL_Disconnect(); } else if( msg->pData[0] == 0xFF && msg->pData[1] == 0xFF && msg->pData[2] == 0xFF && msg->pData[3] == 0xFF && msg->pData[4] == 0x66 && msg->pData[5] == 0x0A ) { dataoffset = 6; while( 1 ) { servadr.type = NA_IP; Q_memcpy( servadr.ip, &msg->pData[dataoffset], sizeof(servadr.ip)); servadr.port = *(unsigned short *)&msg->pData[dataoffset + 4]; if( !servadr.port ) break; MsgDev( D_INFO, "Found server: %s\n", NET_AdrToString( servadr )); NET_Config( true ); // allow remote Netchan_OutOfBandPrint( NS_CLIENT, servadr, "info %i", PROTOCOL_VERSION ); dataoffset += 6; } } else if( clgame.dllFuncs.pfnConnectionlessPacket( &from, args, buf, &len )) { // user out of band message (must be handled in CL_ConnectionlessPacket) if( len > 0 ) Netchan_OutOfBand( NS_SERVER, from, len, buf ); } else MsgDev( D_ERROR, "bad connectionless packet from %s:\n%s\n", NET_AdrToString( from ), args ); }
void CL_Frame ( int msec,float fractionMsec ) { if ( !com_cl_running->integer ) { return; } // load the ref / cgame if needed CL_StartHunkUsers(); if ( cls.state == CA_DISCONNECTED && !( Key_GetCatcher( ) & KEYCATCH_UI ) && !com_sv_running->integer ) { // if disconnected, bring up the menu if (!CL_CheckPendingCinematic()) // this avoid having the menu flash for one frame before pending cinematics { UI_SetActiveMenu( "mainMenu",NULL ); } } // if recording an avi, lock to a fixed fps if ( cl_avidemo->integer ) { // save the current screen if ( cls.state == CA_ACTIVE ) { if (cl_avidemo->integer > 0) { Cbuf_ExecuteText( EXEC_NOW, "screenshot silent\n" ); } else { Cbuf_ExecuteText( EXEC_NOW, "screenshot_tga silent\n" ); } } // fixed time for next frame if (cl_avidemo->integer > 0) { msec = 1000 / cl_avidemo->integer; } else { msec = 1000 / -cl_avidemo->integer; } } // save the msec before checking pause cls.realFrametime = msec; // decide the simulation time cls.frametime = msec; if(cl_framerate->integer) { avgFrametime+=msec; char mess[256]; if(!(frameCount&0x1f)) { sprintf(mess,"Frame rate=%f\n\n",1000.0f*(1.0/(avgFrametime/32.0f))); // OutputDebugString(mess); Com_Printf(mess); avgFrametime=0.0f; } frameCount++; } cls.frametimeFraction=fractionMsec; cls.realtime += msec; cls.realtimeFraction+=fractionMsec; if (cls.realtimeFraction>=1.0f) { if (cl_newClock&&cl_newClock->integer) { cls.realtime++; } cls.realtimeFraction-=1.0f; } if ( cl_timegraph->integer ) { SCR_DebugGraph ( cls.realFrametime * 0.25, 0 ); } // see if we need to update any userinfo CL_CheckUserinfo(); // if we haven't gotten a packet in a long time, // drop the connection CL_CheckTimeout(); // send intentions now CL_SendCmd(); // resend a connection request if necessary CL_CheckForResend(); // decide on the serverTime to render CL_SetCGameTime(); if (cl_pano->integer && cls.state == CA_ACTIVE) { //grab some panoramic shots int i = 1; int pref = cl_pano->integer; int oldnoprint = cl_noprint->integer; Con_Close(); cl_noprint->integer = 1; //hide the screen shot msgs for (; i <= cl_panoNumShots->integer; i++) { Cvar_SetValue( "pano", i ); SCR_UpdateScreen();// update the screen Cbuf_ExecuteText( EXEC_NOW, va("screenshot %dpano%02d\n", pref, i) ); //grab this screen } Cvar_SetValue( "pano", 0 ); //done cl_noprint->integer = oldnoprint; } if (cl_skippingcin->integer && !cl_endcredits->integer && !com_developer->integer ) { if (cl_skippingcin->modified){ S_StopSounds(); //kill em all but music cl_skippingcin->modified=qfalse; Com_Printf (S_COLOR_YELLOW "%s", SE_GetString("CON_TEXT_SKIPPING")); SCR_UpdateScreen(); } } else { // update the screen SCR_UpdateScreen(); } // update audio S_Update(); // advance local effects for next frame SCR_RunCinematic(); Con_RunConsole(); cls.framecount++; }
/* =================== Key_Event Called by the system for both key up and key down events =================== */ void Key_Event( int key, qboolean down ) { const char *kb; char cmd[1024]; //Con_Printf( "Keycode %d\n", key ); if ( key > 255 || key < 0) { Con_Printf ("Keynum %d out of range\n", key); return; } // update auto-repeat status and BUTTON_ANY status keys[key].down = down; if( down ) { //keys[key].repeats++; if( key != K_BACKSPACE && key != K_PAUSE && keys[key].repeats > 1 ) { if( cls.key_dest == key_game ) { // ignore most autorepeats return; } } } else { keys[key].repeats = 0; } // console key is hardcoded, so the user can never unbind it if( key == '`' || key == '~' ) { // we are in typing mode, so don't switch to console if( cls.key_dest == key_message || !down ) return; Con_ToggleConsole_f(); return; } // escape is always handled specially if( key == K_ESCAPE && down ) { switch( cls.key_dest ) { case key_game: if( host.mouse_visible && cls.state != ca_cinematic ) { clgame.dllFuncs.pfnKey_Event( down, key, keys[key].binding ); return; // handled in client.dll } break; case key_message: Key_Message( key ); return; case key_console: if( cls.state == ca_active && !cl.background ) Key_SetKeyDest( key_game ); else UI_SetActiveMenu( true ); return; case key_menu: UI_KeyEvent( key, true ); return; default: MsgDev( D_ERROR, "Key_Event: bad cls.key_dest\n" ); return; } } if( cls.key_dest == key_menu ) { // only non printable keys passed UI_KeyEvent( key, down ); return; } // key up events only perform actions if the game key binding is // a button command (leading + sign). These will be processed even in // console mode and menu mode, to keep the character from continuing // an action started before a mode switch. if( !down ) { kb = keys[key].binding; if( cls.key_dest == key_game && ( key != K_ESCAPE )) clgame.dllFuncs.pfnKey_Event( down, key, kb ); Key_AddKeyUpCommands( key, kb ); return; } // distribute the key down event to the apropriate handler if( cls.key_dest == key_game ) { if( cls.state == ca_cinematic ) { // only escape passed when cinematic is playing // HLFX 0.6 bug: crash in vgui3.dll while press +attack during movie playback if( key != K_ESCAPE || !down ) return; } else if( host.mouse_visible ) return; // send the bound action kb = keys[key].binding; if( !clgame.dllFuncs.pfnKey_Event( down, key, keys[key].binding )) { // handled in client.dll } else if( kb != NULL ) { if( kb[0] == '+' ) { int i; char button[1024], *buttonPtr; for( i = 0, buttonPtr = button; ; i++ ) { if( kb[i] == ';' || !kb[i] ) { *buttonPtr = '\0'; if( button[0] == '+' ) { Q_sprintf( cmd, "%s %i\n", button, key ); Cbuf_AddText( cmd ); } else { // down-only command Cbuf_AddText( button ); Cbuf_AddText( "\n" ); } buttonPtr = button; while (( kb[i] <= ' ' || kb[i] == ';' ) && kb[i] != 0 ) i++; } *buttonPtr++ = kb[i]; if( !kb[i] ) break; } } else { // down-only command Cbuf_AddText( kb ); Cbuf_AddText( "\n" ); } } } else if( cls.key_dest == key_console ) { Key_Console( key ); } else if( cls.key_dest == key_message ) { Key_Message( key ); } }
/* ================= Host_Error ================= */ void Host_Error( const char *error, ... ) { static char hosterror1[MAX_SYSPATH]; static char hosterror2[MAX_SYSPATH]; static qboolean recursive = false; va_list argptr; if( host.mouse_visible && !CL_IsInMenu( )) { // hide VGUI mouse #ifdef XASH_SDL SDL_ShowCursor( false ); #endif host.mouse_visible = false; } va_start( argptr, error ); Q_vsprintf( hosterror1, error, argptr ); va_end( argptr ); CL_WriteMessageHistory (); // before Q_error call if( host.framecount < 3 ) { Sys_Error( "Host_InitError: %s", hosterror1 ); } else if( host.framecount == host.errorframe ) { Sys_Error( "Host_MultiError: %s", hosterror2 ); return; } else { if( host.developer > 0 ) { UI_SetActiveMenu( false ); Key_SetKeyDest( key_console ); Msg( "^1Host_Error: ^7%s", hosterror1 ); } else MSGBOX2( hosterror1 ); } // host is shutting down. don't invoke infinite loop if( host.state == HOST_SHUTDOWN ) return; if( recursive ) { Msg( "Host_RecursiveError: %s", hosterror2 ); Sys_Error( hosterror1 ); return; // don't multiple executes } recursive = true; Q_strncpy( hosterror2, hosterror1, MAX_SYSPATH ); host.errorframe = host.framecount; // to avoid multple calls per frame Q_sprintf( host.finalmsg, "Server crashed: %s", hosterror1 ); // clear cmd buffer to prevent execution of any commands Cbuf_Clear(); SV_Shutdown( false ); CL_Drop(); // drop clients // recreate world if required CL_ClearEdicts (); // release all models Mod_ClearAll( false ); recursive = false; Host_AbortCurrentFrame(); }
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; }
void CL_Frame ( int msec,float fractionMsec ) { checkAutoSave(); //saves the game immediately after starting a level if ( !com_cl_running->integer ) { return; } // load the ref / cgame if needed CL_StartHunkUsers(); #if defined (_XBOX)// && !defined(_DEBUG) // Play the intro movies once extern bool Sys_QuickStart( void ); static bool firstRun = true; if(firstRun) { // SP_DoLicense(); SP_DisplayLogos(); } #endif #if defined (_XBOX) //xbox doesn't load ui in StartHunkUsers, so check it here // load ui if needed if ( !cls.uiStarted && cls.state != CA_CINEMATIC) { cls.uiStarted = qtrue; SCR_StopCinematic(); CL_InitUI(); } #endif if ( cls.state == CA_DISCONNECTED && !( cls.keyCatchers & KEYCATCH_UI ) && !com_sv_running->integer ) { // if disconnected, bring up the menu #ifdef _XBOX if (firstRun && !Sys_QuickStart()) { // Fresh boot UI_SetActiveMenu("splashMenu", NULL); } else if (firstRun) { // Came from MP: UI_SetActiveMenu("mainMenu", NULL); extern void XB_Startup( XBStartupState startupState ); XB_Startup( STARTUP_LOAD_SETTINGS ); } else { #ifdef XBOX_DEMO // Quitting the demo returns to the IIS, and restores settings: Settings.RestoreDefaults(); Settings.SetAll(); UI_SetActiveMenu("splashMenu", NULL); #else UI_SetActiveMenu("mainMenu", NULL); #endif } #else if (!CL_CheckPendingCinematic()) // this avoid having the menu flash for one frame before pending cinematics { UI_SetActiveMenu("mainMenu", NULL); } #endif S_StartBackgroundTrack("music/mp/MP_action4.mp3","",0); } #ifdef _XBOX firstRun = false; #endif // if recording an avi, lock to a fixed fps if ( cl_avidemo->integer ) { // save the current screen if ( cls.state == CA_ACTIVE ) { if (cl_avidemo->integer > 0) { Cbuf_ExecuteText( EXEC_NOW, "screenshot silent\n" ); } else { Cbuf_ExecuteText( EXEC_NOW, "screenshot_tga silent\n" ); } } // fixed time for next frame if (cl_avidemo->integer > 0) { msec = 1000 / cl_avidemo->integer; } else { msec = 1000 / -cl_avidemo->integer; } } // save the msec before checking pause cls.realFrametime = msec; // decide the simulation time cls.frametime = msec; //if(cl_framerate->integer) //{ // avgFrametime+=msec; // char mess[256]; // if(!(frameCount&0x1f)) // { // sprintf(mess,"Frame rate=%f\n\n",1000.0f*(1.0/(avgFrametime/32.0f))); //// OutputDebugString(mess); // Com_Printf(mess); // avgFrametime=0.0f; // } // frameCount++; //} // Always calculate framerate, bias the LOD if low avgFrametime+=msec; extern bool in_camera; float framerate = 1000.0f*(1.0/(avgFrametime/32.0f)); static int lodFrameCount = 0; int bias = Cvar_VariableIntegerValue("r_lodbias"); if(!(frameCount&0x1f)) { if(cl_framerate->integer) { char mess[256]; sprintf(mess,"Frame rate=%f LOD=%d\n\n",framerate,bias); Com_Printf(mess); } avgFrametime=0.0f; // If we drop below 20FPS, pull down the LOD bias if(framerate < 20.0f && bias == 0) { bias++; Cvar_SetValue("r_lodbias", bias); lodFrameCount = -1; } lodFrameCount++; if(lodFrameCount==5 && bias > 0) { bias--; Cvar_SetValue("r_lodBias", bias); lodFrameCount = 0; } } frameCount++; if(in_camera) { // No LOD stuff during cutscenes Cvar_SetValue("r_lodBias", 0); } cls.frametimeFraction=fractionMsec; cls.realtime += msec; cls.realtimeFraction+=fractionMsec; if (cls.realtimeFraction>=1.0f) { if (cl_newClock&&cl_newClock->integer) { cls.realtime++; } cls.realtimeFraction-=1.0f; } #ifndef _XBOX if ( cl_timegraph->integer ) { SCR_DebugGraph ( cls.realFrametime * 0.25, 0 ); } #endif #ifdef _XBOX //Check on the hot swappable button states. CL_UpdateHotSwap(); #endif // see if we need to update any userinfo CL_CheckUserinfo(); // if we haven't gotten a packet in a long time, // drop the connection CL_CheckTimeout(); // send intentions now CL_SendCmd(); // resend a connection request if necessary CL_CheckForResend(); // decide on the serverTime to render CL_SetCGameTime(); if (cl_pano->integer && cls.state == CA_ACTIVE) { //grab some panoramic shots int i = 1; int pref = cl_pano->integer; int oldnoprint = cl_noprint->integer; Con_Close(); cl_noprint->integer = 1; //hide the screen shot msgs for (; i <= cl_panoNumShots->integer; i++) { Cvar_SetValue( "pano", i ); SCR_UpdateScreen();// update the screen Cbuf_ExecuteText( EXEC_NOW, va("screenshot %dpano%02d\n", pref, i) ); //grab this screen } Cvar_SetValue( "pano", 0 ); //done cl_noprint->integer = oldnoprint; } if (cl_skippingcin->integer && !cl_endcredits->integer && !com_developer->integer ) { if (cl_skippingcin->modified){ S_StopSounds(); //kill em all but music cl_skippingcin->modified=qfalse; Com_Printf (va(S_COLOR_YELLOW"%s"), SE_GetString("CON_TEXT_SKIPPING")); SCR_UpdateScreen(); } } else { // update the screen SCR_UpdateScreen(); #if defined(_XBOX) && !defined(FINAL_BUILD) if (D3DPERF_QueryRepeatFrame()) SCR_UpdateScreen(); #endif } // update audio S_Update(); #ifdef _IMMERSION FF_Update(); #endif // _IMMERSION // advance local effects for next frame SCR_RunCinematic(); Con_RunConsole(); cls.framecount++; }
int baseq3_ui_vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) { #else int vmMain( int command, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9, int arg10, int arg11 ) { #endif // IOS switch ( command ) { case UI_GETAPIVERSION: return UI_API_VERSION; case UI_INIT: UI_Init(); return 0; case UI_UPDATE_GLCONFIG: UI_UpdateGLConfig(); return 0; case UI_SHUTDOWN: UI_Shutdown(); return 0; case UI_KEY_EVENT: UI_KeyEvent( arg0, arg1 ); return 0; case UI_MOUSE_EVENT: UI_MouseEvent( arg0, arg1 ); return 0; case UI_REFRESH: UI_Refresh( arg0 ); return 0; case UI_IS_FULLSCREEN: return UI_IsFullscreen(); case UI_SET_ACTIVE_MENU: UI_SetActiveMenu( arg0 ); return 0; case UI_CONSOLE_COMMAND: return UI_ConsoleCommand(arg0); case UI_DRAW_CONNECT_SCREEN: UI_DrawConnectScreen( arg0 ); return 0; case UI_SELECT_AND_PRESS: UI_SelectAndPress( arg0, arg1 ); return 0; case UI_HASUNIQUECDKEY: // mod authors need to observe this return qtrue; // bk010117 - change this to qfalse for mods! } return -1; } /* ================ cvars ================ */ typedef struct { vmCvar_t *vmCvar; char *cvarName; char *defaultString; int cvarFlags; } cvarTable_t; vmCvar_t ui_ffa_fraglimit; vmCvar_t ui_ffa_timelimit; vmCvar_t ui_tourney_fraglimit; vmCvar_t ui_tourney_timelimit; vmCvar_t ui_team_fraglimit; vmCvar_t ui_team_timelimit; vmCvar_t ui_team_friendly; vmCvar_t ui_ctf_capturelimit; vmCvar_t ui_ctf_timelimit; vmCvar_t ui_ctf_friendly; vmCvar_t ui_arenasFile; vmCvar_t ui_botsFile; vmCvar_t ui_spScores1; vmCvar_t ui_spScores2; vmCvar_t ui_spScores3; vmCvar_t ui_spScores4; vmCvar_t ui_spScores5; vmCvar_t ui_spAwards; vmCvar_t ui_spVideos; vmCvar_t ui_spSkill; vmCvar_t ui_spSelection; vmCvar_t ui_browserMaster; vmCvar_t ui_browserGameType; vmCvar_t ui_browserSortKey; vmCvar_t ui_browserShowFull; vmCvar_t ui_browserShowEmpty; vmCvar_t ui_brassTime; vmCvar_t ui_drawCrosshair; vmCvar_t ui_drawCrosshairNames; vmCvar_t ui_marks; vmCvar_t ui_server1; vmCvar_t ui_server2; vmCvar_t ui_server3; vmCvar_t ui_server4; vmCvar_t ui_server5; vmCvar_t ui_server6; vmCvar_t ui_server7; vmCvar_t ui_server8; vmCvar_t ui_server9; vmCvar_t ui_server10; vmCvar_t ui_server11; vmCvar_t ui_server12; vmCvar_t ui_server13; vmCvar_t ui_server14; vmCvar_t ui_server15; vmCvar_t ui_server16; vmCvar_t ui_cdkeychecked; // bk001129 - made static to avoid aliasing. static cvarTable_t cvarTable[] = { { &ui_ffa_fraglimit, "ui_ffa_fraglimit", "20", CVAR_ARCHIVE }, { &ui_ffa_timelimit, "ui_ffa_timelimit", "0", CVAR_ARCHIVE }, { &ui_tourney_fraglimit, "ui_tourney_fraglimit", "0", CVAR_ARCHIVE }, { &ui_tourney_timelimit, "ui_tourney_timelimit", "15", CVAR_ARCHIVE }, { &ui_team_fraglimit, "ui_team_fraglimit", "0", CVAR_ARCHIVE }, { &ui_team_timelimit, "ui_team_timelimit", "20", CVAR_ARCHIVE }, { &ui_team_friendly, "ui_team_friendly", "1", CVAR_ARCHIVE }, { &ui_ctf_capturelimit, "ui_ctf_capturelimit", "8", CVAR_ARCHIVE }, { &ui_ctf_timelimit, "ui_ctf_timelimit", "30", CVAR_ARCHIVE }, { &ui_ctf_friendly, "ui_ctf_friendly", "0", CVAR_ARCHIVE }, { &ui_arenasFile, "g_arenasFile", "", CVAR_INIT|CVAR_ROM }, { &ui_botsFile, "g_botsFile", "", CVAR_INIT|CVAR_ROM }, { &ui_spScores1, "g_spScores1", "", CVAR_ARCHIVE | CVAR_ROM }, { &ui_spScores2, "g_spScores2", "", CVAR_ARCHIVE | CVAR_ROM }, { &ui_spScores3, "g_spScores3", "", CVAR_ARCHIVE | CVAR_ROM }, { &ui_spScores4, "g_spScores4", "", CVAR_ARCHIVE | CVAR_ROM }, { &ui_spScores5, "g_spScores5", "", CVAR_ARCHIVE | CVAR_ROM }, { &ui_spAwards, "g_spAwards", "", CVAR_ARCHIVE | CVAR_ROM }, { &ui_spVideos, "g_spVideos", "", CVAR_ARCHIVE | CVAR_ROM }, { &ui_spSkill, "g_spSkill", "2", CVAR_ARCHIVE | CVAR_LATCH }, { &ui_spSelection, "ui_spSelection", "", CVAR_ROM }, { &ui_browserMaster, "ui_browserMaster", "0", CVAR_ARCHIVE }, { &ui_browserGameType, "ui_browserGameType", "0", CVAR_ARCHIVE }, { &ui_browserSortKey, "ui_browserSortKey", "4", CVAR_ARCHIVE }, { &ui_browserShowFull, "ui_browserShowFull", "1", CVAR_ARCHIVE }, { &ui_browserShowEmpty, "ui_browserShowEmpty", "1", CVAR_ARCHIVE }, { &ui_brassTime, "cg_brassTime", "2500", CVAR_ARCHIVE }, { &ui_drawCrosshair, "cg_drawCrosshair", "4", CVAR_ARCHIVE }, { &ui_drawCrosshairNames, "cg_drawCrosshairNames", "1", CVAR_ARCHIVE }, { &ui_marks, "cg_marks", "1", CVAR_ARCHIVE }, { &ui_server1, "server1", "", CVAR_ARCHIVE }, { &ui_server2, "server2", "", CVAR_ARCHIVE }, { &ui_server3, "server3", "", CVAR_ARCHIVE }, { &ui_server4, "server4", "", CVAR_ARCHIVE }, { &ui_server5, "server5", "", CVAR_ARCHIVE }, { &ui_server6, "server6", "", CVAR_ARCHIVE }, { &ui_server7, "server7", "", CVAR_ARCHIVE }, { &ui_server8, "server8", "", CVAR_ARCHIVE }, { &ui_server9, "server9", "", CVAR_ARCHIVE }, { &ui_server10, "server10", "", CVAR_ARCHIVE }, { &ui_server11, "server11", "", CVAR_ARCHIVE }, { &ui_server12, "server12", "", CVAR_ARCHIVE }, { &ui_server13, "server13", "", CVAR_ARCHIVE }, { &ui_server14, "server14", "", CVAR_ARCHIVE }, { &ui_server15, "server15", "", CVAR_ARCHIVE }, { &ui_server16, "server16", "", CVAR_ARCHIVE }, { &ui_cdkeychecked, "ui_cdkeychecked", "0", CVAR_ROM } }; // bk001129 - made static to avoid aliasing static int cvarTableSize = sizeof(cvarTable) / sizeof(cvarTable[0]); /* ================= UI_RegisterCvars ================= */ void UI_RegisterCvars( void ) { int i; cvarTable_t *cv; for ( i = 0, cv = cvarTable ; i < cvarTableSize ; i++, cv++ ) { trap_Cvar_Register( cv->vmCvar, cv->cvarName, cv->defaultString, cv->cvarFlags ); } }
void CL_Frame ( int msec,float fractionMsec ) { if ( !com_cl_running->integer ) { return; } // load the ref / cgame if needed CL_StartHunkUsers(); #if defined (_XBOX)// && !defined(_DEBUG) // Play the intro movies once static bool firstRun = true; if(firstRun) { // SP_DoLicense(); SP_DisplayLogos(); } #endif #if defined (_XBOX) //xbox doesn't load ui in StartHunkUsers, so check it here // load ui if needed if ( !cls.uiStarted && cls.state != CA_CINEMATIC) { cls.uiStarted = qtrue; SCR_StopCinematic(); CL_InitUI(); } #endif if ( cls.state == CA_DISCONNECTED && !( cls.keyCatchers & KEYCATCH_UI ) && !com_sv_running->integer ) { // if disconnected, bring up the menu if (!CL_CheckPendingCinematic()) // this avoid having the menu flash for one frame before pending cinematics { #ifdef _XBOX if (firstRun) { UI_SetActiveMenu("splashMenu", NULL); } else #endif UI_SetActiveMenu( "mainMenu",NULL ); } } #ifdef _XBOX firstRun = false; #endif // if recording an avi, lock to a fixed fps if ( cl_avidemo->integer ) { // save the current screen if ( cls.state == CA_ACTIVE ) { if (cl_avidemo->integer > 0) { Cbuf_ExecuteText( EXEC_NOW, "screenshot silent\n" ); } else { Cbuf_ExecuteText( EXEC_NOW, "screenshot_tga silent\n" ); } } // fixed time for next frame if (cl_avidemo->integer > 0) { msec = 1000 / cl_avidemo->integer; } else { msec = 1000 / -cl_avidemo->integer; } } // save the msec before checking pause cls.realFrametime = msec; // decide the simulation time cls.frametime = msec; if(cl_framerate->integer) { avgFrametime+=msec; char mess[256]; if(!(frameCount&0x1f)) { sprintf(mess,"Frame rate=%f\n\n",1000.0f*(1.0/(avgFrametime/32.0f))); // OutputDebugString(mess); Com_Printf(mess); avgFrametime=0.0f; } frameCount++; } cls.frametimeFraction=fractionMsec; cls.realtime += msec; cls.realtimeFraction+=fractionMsec; if (cls.realtimeFraction>=1.0f) { if (cl_newClock&&cl_newClock->integer) { cls.realtime++; } cls.realtimeFraction-=1.0f; } #ifndef _XBOX if ( cl_timegraph->integer ) { SCR_DebugGraph ( cls.realFrametime * 0.25, 0 ); } #endif #ifdef _XBOX //Check on the hot swappable button states. CL_UpdateHotSwap(); #endif // see if we need to update any userinfo CL_CheckUserinfo(); // if we haven't gotten a packet in a long time, // drop the connection CL_CheckTimeout(); // send intentions now CL_SendCmd(); // resend a connection request if necessary CL_CheckForResend(); // decide on the serverTime to render CL_SetCGameTime(); if (cl_pano->integer && cls.state == CA_ACTIVE) { //grab some panoramic shots int i = 1; int pref = cl_pano->integer; int oldnoprint = cl_noprint->integer; Con_Close(); cl_noprint->integer = 1; //hide the screen shot msgs for (; i <= cl_panoNumShots->integer; i++) { Cvar_SetValue( "pano", i ); SCR_UpdateScreen();// update the screen Cbuf_ExecuteText( EXEC_NOW, va("screenshot %dpano%02d\n", pref, i) ); //grab this screen } Cvar_SetValue( "pano", 0 ); //done cl_noprint->integer = oldnoprint; } if (cl_skippingcin->integer && !cl_endcredits->integer && !com_developer->integer ) { if (cl_skippingcin->modified){ S_StopSounds(); //kill em all but music cl_skippingcin->modified=qfalse; Com_Printf (va(S_COLOR_YELLOW"%s"), SE_GetString("CON_TEXT_SKIPPING")); SCR_UpdateScreen(); } } else { // update the screen SCR_UpdateScreen(); #if defined(_XBOX) && !defined(FINAL_BUILD) if (D3DPERF_QueryRepeatFrame()) SCR_UpdateScreen(); #endif } // update audio S_Update(); #ifdef _IMMERSION FF_Update(); #endif // _IMMERSION // advance local effects for next frame SCR_RunCinematic(); Con_RunConsole(); cls.framecount++; }
/* ================== CL_ParseServerData ================== */ void CL_ParseServerData( sizebuf_t *msg ) { string gamefolder; qboolean background; int i; MsgDev( D_NOTE, "Serverdata packet received.\n" ); cls.demowaiting = false; // server is changed clgame.load_sequence++; // now all hud sprites are invalid // wipe the client_t struct if( !cls.changelevel && !cls.changedemo ) CL_ClearState (); cls.state = ca_connected; // parse protocol version number i = BF_ReadLong( msg ); cls.serverProtocol = i; if( i != PROTOCOL_VERSION ) Host_Error( "Server uses invalid protocol (%i should be %i)\n", i, PROTOCOL_VERSION ); cl.servercount = BF_ReadLong( msg ); cl.checksum = BF_ReadLong( msg ); cl.playernum = BF_ReadByte( msg ); cl.maxclients = BF_ReadByte( msg ); clgame.maxEntities = BF_ReadWord( msg ); clgame.maxEntities = bound( 600, clgame.maxEntities, 4096 ); Q_strncpy( clgame.mapname, BF_ReadString( msg ), MAX_STRING ); Q_strncpy( clgame.maptitle, BF_ReadString( msg ), MAX_STRING ); background = BF_ReadOneBit( msg ); Q_strncpy( gamefolder, BF_ReadString( msg ), MAX_STRING ); host.features = (uint)BF_ReadLong( msg ); if( cl.maxclients > 1 && host.developer < 1 ) host.developer++; // set the background state if( cls.demoplayback && ( cls.demonum != -1 )) { // re-init mouse host.mouse_visible = false; cl.background = true; } else cl.background = background; if( cl.background ) // tell the game parts about background state Cvar_FullSet( "cl_background", "1", CVAR_READ_ONLY ); else Cvar_FullSet( "cl_background", "0", CVAR_READ_ONLY ); if( !cls.changelevel ) { // continue playing if we are changing level S_StopBackgroundTrack (); } #if 0 // NOTE: this is not tested as well. Use with precaution CL_ChangeGame( gamefolder, false ); #endif if( !cls.changedemo ) UI_SetActiveMenu( cl.background ); cl.refdef.viewentity = cl.playernum + 1; // always keep viewent an actual menu.globals->maxClients = cl.maxclients; Q_strncpy( menu.globals->maptitle, clgame.maptitle, sizeof( menu.globals->maptitle )); if( cl.maxclients > 1 && r_decals->value > mp_decals->value ) Cvar_SetFloat( "r_decals", mp_decals->value ); if( !cls.changelevel && !cls.changedemo ) CL_InitEdicts (); // re-arrange edicts // get splash name if( cls.demoplayback && ( cls.demonum != -1 )) Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", cls.demoname, glState.wideScreen ? "16x9" : "4x3" )); else Cvar_Set( "cl_levelshot_name", va( "levelshots/%s_%s", clgame.mapname, glState.wideScreen ? "16x9" : "4x3" )); Cvar_SetFloat( "scr_loading", 0.0f ); // reset progress bar if(( cl_allow_levelshots->integer && !cls.changelevel ) || cl.background ) { if( !FS_FileExists( va( "%s.bmp", cl_levelshot_name->string ), true )) Cvar_Set( "cl_levelshot_name", "*black" ); // render a black screen cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime) } if( scr_dark->integer ) { screenfade_t *sf = &clgame.fade; client_textmessage_t *title; title = CL_TextMessageGet( "GAMETITLE" ); if( title ) { // get settings from titles.txt sf->fadeEnd = title->holdtime + title->fadeout; sf->fadeReset = title->fadeout; } else sf->fadeEnd = sf->fadeReset = 4.0f; sf->fadeFlags = FFADE_IN; sf->fader = sf->fadeg = sf->fadeb = 0; sf->fadealpha = 255; sf->fadeSpeed = (float)sf->fadealpha / sf->fadeReset; sf->fadeReset += cl.time; sf->fadeEnd += sf->fadeReset; Cvar_SetFloat( "v_dark", 0.0f ); } // need to prep refresh at next oportunity cl.video_prepped = false; cl.audio_prepped = false; Q_memset( &clgame.movevars, 0, sizeof( clgame.movevars )); Q_memset( &clgame.oldmovevars, 0, sizeof( clgame.oldmovevars )); }
/* ================= UI_Main_Callback ================= */ static void UI_Main_Callback( void *self, int event ) { menuCommon_s *item = (menuCommon_s *)self; switch( item->id ) { case ID_QUIT_BUTTON: if( event == QM_PRESSED ) ((menuBitmap_s *)self)->focusPic = ART_CLOSEBTN_D; else ((menuBitmap_s *)self)->focusPic = ART_CLOSEBTN_F; break; case ID_MINIMIZE: if( event == QM_PRESSED ) ((menuBitmap_s *)self)->focusPic = ART_MINIMIZE_D; else ((menuBitmap_s *)self)->focusPic = ART_MINIMIZE_F; break; } if( event != QM_ACTIVATED ) return; switch( item->id ) { case ID_CONSOLE: UI_SetActiveMenu( FALSE ); KEY_SetDest( KEY_CONSOLE ); break; case ID_RESUME: UI_CloseMenu(); break; case ID_NEWGAME: if( CL_IsActive( )) UI_PromptDialog(); else UI_Main_NewGame(); break; case ID_MULTIPLAYER: UI_MultiPlayer_Menu(); break; case ID_CONFIGURATION: UI_Options_Menu(); break; case ID_SAVERESTORE: if( CL_IsActive( )) UI_SaveLoad_Menu(); else UI_LoadGame_Menu(); break; case ID_CUSTOMGAME: UI_CustomGame_Menu(); break; case ID_PREVIEWS: SHELL_EXECUTE( MenuStrings[HINT_PREVIEWS_CMD], NULL, false ); break; case ID_QUIT: case ID_QUIT_BUTTON: UI_QuitDialog(); break; case ID_MINIMIZE: CLIENT_COMMAND( FALSE, "minimize\n" ); break; case ID_YES: if( !( uiMain.quitMessage.generic.flags & QMF_HIDDEN )) CLIENT_COMMAND( FALSE, "quit\n" ); else UI_Main_NewGame(); break; case ID_NO: if( !( uiMain.quitMessage.generic.flags & QMF_HIDDEN )) UI_QuitDialog(); else UI_PromptDialog(); break; } }
void CL_DataPad_f(void) { if (cls.uiStarted && cls.cgameStarted && (cls.state == CA_ACTIVE) ) { UI_SetActiveMenu("datapad",NULL); } }
/* ==================== CL_PlayDemo_f playdemo <demoname> ==================== */ void CL_PlayDemo_f( void ) { string filename; string demoname; int i; if( Cmd_Argc() != 2 ) { Msg( "Usage: playdemo <demoname>\n" ); return; } if( cls.demoplayback ) { CL_StopPlayback(); } if( cls.demorecording ) { Msg( "Can't playback during demo record.\n"); return; } Q_strncpy( demoname, Cmd_Argv( 1 ), sizeof( demoname ) - 1 ); Q_snprintf( filename, sizeof( filename ), "demos/%s.dem", demoname ); if( !FS_FileExists( filename, true )) { MsgDev( D_ERROR, "couldn't open %s\n", filename ); cls.demonum = -1; // stop demo loop return; } cls.demofile = FS_Open( filename, "rb", true ); Q_strncpy( cls.demoname, demoname, sizeof( cls.demoname )); Q_strncpy( menu.globals->demoname, demoname, sizeof( menu.globals->demoname )); // read in the m_DemoHeader FS_Read( cls.demofile, &demo.header, sizeof( demoheader_t )); if( demo.header.id != IDEMOHEADER ) { MsgDev( D_ERROR, "%s is not a demo file\n", filename ); FS_Close( cls.demofile ); cls.demofile = NULL; cls.demonum = -1; // stop demo loop return; } if( demo.header.net_protocol != PROTOCOL_VERSION || demo.header.dem_protocol != DEMO_PROTOCOL ) { MsgDev( D_ERROR, "demo protocol outdated\n" "Demo file protocols Network(%i), Demo(%i)\n" "Server protocol is at Network(%i), Demo(%i)\n", demo.header.net_protocol, demo.header.dem_protocol, PROTOCOL_VERSION, DEMO_PROTOCOL ); FS_Close( cls.demofile ); cls.demofile = NULL; cls.demonum = -1; // stop demo loop return; } // now read in the directory structure. FS_Seek( cls.demofile, demo.header.directory_offset, SEEK_SET ); FS_Read( cls.demofile, &demo.directory.numentries, sizeof( int )); if( demo.directory.numentries < 1 || demo.directory.numentries > 1024 ) { MsgDev( D_ERROR, "demo had bogus # of directory entries: %i\n", demo.directory.numentries ); FS_Close( cls.demofile ); cls.demofile = NULL; cls.demonum = -1; // stop demo loop cls.changedemo = false; return; } if( cls.changedemo ) { S_StopAllSounds(); SCR_BeginLoadingPlaque( false ); CL_ClearState (); CL_InitEdicts (); // re-arrange edicts } else { // NOTE: at this point demo is still valid CL_Disconnect(); Host_ShutdownServer(); Con_Close(); UI_SetActiveMenu( false ); } // allocate demo entries demo.directory.entries = Mem_Alloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries ); for( i = 0; i < demo.directory.numentries; i++ ) { FS_Read( cls.demofile, &demo.directory.entries[i], sizeof( demoentry_t )); } demo.entryIndex = 0; demo.entry = &demo.directory.entries[demo.entryIndex]; FS_Seek( cls.demofile, demo.entry->offset, SEEK_SET ); cls.demoplayback = true; cls.state = ca_connected; cl.background = (cls.demonum != -1) ? true : false; demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, net_qport->integer ); demo.framecount = 0; cls.lastoutgoingcommand = -1; cls.nextcmdtime = host.realtime; // g-cont. is this need? Q_strncpy( cls.servername, demoname, sizeof( cls.servername )); // begin a playback demo }