/* ================ SV_DrawDebugTriangles Called from renderer for debug purposes ================ */ void SV_DrawDebugTriangles( void ) { #ifndef XASH_DEDICATED if( Host_IsDedicated() ) return; if( svgame.physFuncs.DrawNormalTriangles != NULL ) { // draw solid overlay svgame.physFuncs.DrawNormalTriangles (); } if( svgame.physFuncs.DrawDebugTriangles != NULL ) { // debug draws only pglDisable( GL_BLEND ); pglDepthMask( GL_FALSE ); pglDisable( GL_TEXTURE_2D ); // draw wireframe overlay svgame.physFuncs.DrawDebugTriangles (); pglEnable( GL_TEXTURE_2D ); pglDepthMask( GL_TRUE ); pglEnable( GL_BLEND ); } #endif }
/* ==================== CL_Init ==================== */ void CL_Init( void ) { qboolean loaded; Q_memset( &cls, 0, sizeof( cls ) ); if( Host_IsDedicated() ) return; // nothing running on the client Con_Init(); CL_InitLocal(); R_Init(); // init renderer S_Init(); // init sound // unreliable buffer. unsed for unreliable commands and voice stream BF_Init( &cls.datagram, "cls.datagram", cls.datagram_buf, sizeof( cls.datagram_buf )); IN_TouchInit(); #if defined (__ANDROID__) { char clientlib[256]; Q_snprintf( clientlib, sizeof(clientlib), "%s/" CLIENTDLL, getenv("XASH3D_GAMELIBDIR")); loaded = CL_LoadProgs( clientlib ); if( !loaded ) { Q_snprintf( clientlib, sizeof(clientlib), "%s/" CLIENTDLL, getenv("XASH3D_ENGLIBDIR")); loaded = CL_LoadProgs( clientlib ); } } #else { char clientlib[256]; Com_ResetLibraryError(); if( Sys_GetParmFromCmdLine( "-clientlib", clientlib ) ) loaded = CL_LoadProgs( clientlib ); else loaded = CL_LoadProgs( va( "%s/%s" , GI->dll_path, SI.clientlib )); if( !loaded ) { loaded = CL_LoadProgs( CLIENTDLL ); } } #endif if( loaded ) { cls.initialized = true; cls.keybind_changed = false; cl.maxclients = 1; // allow to drawing player in menu cls.olddemonum = -1; cls.demonum = -1; } else Sys_Warn("Could not load client library:\n%s", Com_GetLibraryError()); }
/* ================ SV_DrawOrthoTriangles Called from renderer for debug purposes ================ */ void SV_DrawOrthoTriangles( void ) { if( Host_IsDedicated() ) return; if( svgame.physFuncs.DrawOrthoTriangles != NULL ) { // draw solid overlay svgame.physFuncs.DrawOrthoTriangles (); } }
/* ================ Sys_Break same as Error ================ */ void Sys_Break( const char *format, ... ) { va_list argptr; char text[MAX_SYSPATH]; DEBUG_BREAK; if( host.state == HOST_ERR_FATAL ) return; // don't multiple executes error_on_exit = true; host.state = HOST_ERR_FATAL; va_start( argptr, format ); Q_vsprintf( text, format, argptr ); va_end( argptr ); if( !Host_IsDedicated() ) { #ifdef XASH_SDL if( host.hWnd ) SDL_HideWindow( host.hWnd ); #endif VID_RestoreGamma(); } if( Host_IsDedicated() || host.developer > 0 ) { Con_ShowConsole( true ); Con_DisableInput(); // disable input line for dedicated server Sys_Print( text ); MSGBOX( text ); Sys_WaitForQuit(); } else { Con_ShowConsole( false ); MSGBOX( text ); } Sys_Quit(); }
/* ================ Sys_Warn Just messagebox ================ */ void Sys_Warn( const char *format, ... ) { va_list argptr; char text[MAX_SYSPATH]; DEBUG_BREAK; va_start( argptr, format ); Q_vsprintf( text, format, argptr ); va_end( argptr ); if( !Host_IsDedicated() ) // dedicated server should not hang on messagebox MSGBOX(text); Msg( "Sys_Warn: %s\n", text ); }
/* ================== Sys_MergeCommandLine ================== */ void Sys_MergeCommandLine( ) { const char *blank = "censored"; int i; if( !host.change_game ) return; for( i = 0; i < host.argc; i++ ) { // second call if( Host_IsDedicated() && !Q_strnicmp( "+menu_", host.argv[i], 6 )) host.argv[i] = (char *)blank; } }
/* ======================= R_ClearStaticEntities e.g. by demo request ======================= */ void R_ClearStaticEntities( void ) { int i; if( Host_IsDedicated() ) return; // clear out efrags in case the level hasn't been reloaded for( i = 0; i < cl.worldmodel->numleafs; i++ ) cl.worldmodel->leafs[i+1].efrags = NULL; clgame.numStatics = 0; CL_ClearEfrags (); }
/* ================ Sys_Error NOTE: we must prepare engine to shutdown before call this ================ */ void Sys_Error( const char *format, ... ) { va_list argptr; char text[MAX_SYSPATH]; DEBUG_BREAK; if( host.state == HOST_ERR_FATAL ) return; // don't execute more than once // make sure that console received last message if( host.change_game ) Sys_Sleep( 200 ); error_on_exit = true; host.state = HOST_ERR_FATAL; va_start( argptr, format ); Q_vsprintf( text, format, argptr ); va_end( argptr ); SV_SysError( text ); if( !Host_IsDedicated() ) { #ifdef XASH_SDL if( host.hWnd ) SDL_HideWindow( host.hWnd ); #endif VID_RestoreGamma(); } if( host.developer > 0 ) { Con_ShowConsole( true ); Con_DisableInput(); // disable input line for dedicated server Sys_Print( text ); // print error message MSGBOX( text ); Sys_WaitForQuit(); } else { Con_ShowConsole( false ); MSGBOX( text ); } Sys_Quit(); }
void CL_Crashed( void ) { // already freed if( host.state == HOST_CRASHED ) return; if( Host_IsDedicated() ) return; if( !cls.initialized ) return; host.state = HOST_CRASHED; CL_Stop_f(); // stop any demos // send a disconnect message to the server CL_SendDisconnectMessage(); // never write video.cfg here because reason to crash may be provoked // with some renderer variables VID_RestoreGamma(); }
//====================================================================== qboolean CL_IsInGame( void ) { if( Host_IsDedicated() ) return true; // always active for dedicated servers if( CL_GetMaxClients() > 1 ) return true; // always active for multiplayer return ( cls.key_dest == key_game ); // active if not menu or console }
/* =============== CL_ChangeGame This is experiment. Use with precaution =============== */ qboolean CL_ChangeGame( const char *gamefolder, qboolean bReset ) { if( Host_IsDedicated() ) return false; if( Q_stricmp( host.gamefolder, gamefolder )) { kbutton_t *mlook, *jlook; qboolean mlook_active = false, jlook_active = false; string mapname, maptitle; int maxEntities; mlook = (kbutton_t *)clgame.dllFuncs.KB_Find( "in_mlook" ); jlook = (kbutton_t *)clgame.dllFuncs.KB_Find( "in_jlook" ); if( mlook && ( mlook->state & 1 )) mlook_active = true; if( jlook && ( jlook->state & 1 )) jlook_active = true; // so reload all images (remote connect) Mod_ClearAll( true ); R_ShutdownImages(); FS_LoadGameInfo( (bReset) ? host.gamefolder : gamefolder ); R_InitImages(); // save parms maxEntities = clgame.maxEntities; Q_strncpy( mapname, clgame.mapname, MAX_STRING ); Q_strncpy( maptitle, clgame.maptitle, MAX_STRING ); Com_ResetLibraryError(); if( !CL_LoadProgs( va( "%s/%s", GI->dll_path, GI->client_lib))) Sys_Warn( "Can't initialize client library\n%s", Com_GetLibraryError() ); // restore parms clgame.maxEntities = maxEntities; Q_strncpy( clgame.mapname, mapname, MAX_STRING ); Q_strncpy( clgame.maptitle, maptitle, MAX_STRING ); // invalidate fonts so we can reloading them again Q_memset( &cls.creditsFont, 0, sizeof( cls.creditsFont )); SCR_InstallParticlePalette(); SCR_LoadCreditsFont(); Con_InvalidateFonts(); SCR_RegisterTextures (); CL_FreeEdicts (); SCR_VidInit (); if( cls.key_dest == key_game ) // restore mouse state clgame.dllFuncs.IN_ActivateMouse(); // restore mlook state if( mlook_active ) Cmd_ExecuteString( "+mlook\n", src_command ); if( jlook_active ) Cmd_ExecuteString( "+jlook\n", src_command ); return true; } return false; }
/* ================ Sys_Print print into window console ================ */ void Sys_Print( const char *pMsg ) { if( !Host_IsDedicated() ) Con_Print( pMsg ); #ifdef _WIN32 { const char *msg; char buffer[32768]; char logbuf[32768]; char *b = buffer; char *c = logbuf; int i = 0; // if the message is REALLY long, use just the last portion of it if( Q_strlen( pMsg ) > sizeof( buffer ) - 1 ) msg = pMsg + Q_strlen( pMsg ) - sizeof( buffer ) + 1; else msg = pMsg; // copy into an intermediate buffer while( msg[i] && (( b - buffer ) < sizeof( buffer ) - 1 )) { if( msg[i] == '\n' && msg[i+1] == '\r' ) { b[0] = '\r'; b[1] = '\n'; c[0] = '\n'; b += 2, c++; i++; } else if( msg[i] == '\r' ) { b[0] = '\r'; b[1] = '\n'; b += 2; } else if( msg[i] == '\n' ) { b[0] = '\r'; b[1] = '\n'; c[0] = '\n'; b += 2, c++; } else if( msg[i] == '\35' || msg[i] == '\36' || msg[i] == '\37' ) { i++; // skip console pseudo graph } else if( IsColorString( &msg[i] )) { i++; // skip color prefix } else { *b = *c = msg[i]; b++, c++; } i++; } *b = *c = 0; // cutoff garbage Sys_PrintLog( logbuf ); Con_WinPrint( buffer ); } #else Sys_PrintLog( pMsg ); #endif if( host.rd.target ) { if(( Q_strlen( pMsg ) + Q_strlen( host.rd.buffer )) > ( host.rd.buffersize - 1 )) { if( host.rd.flush ) { host.rd.flush( host.rd.address, host.rd.target, host.rd.buffer ); *host.rd.buffer = 0; } } Q_strcat( host.rd.buffer, pMsg ); return; } }