From 801b11117f85470a45b36fb829f3dad883c26558 Mon Sep 17 00:00:00 2001 From: g-cont Date: Thu, 1 Mar 2018 00:00:00 +0300 Subject: [PATCH] 01 Mar 2018 --- engine/client/cl_demo.c | 19 ++- engine/client/cl_game.c | 32 ++--- engine/client/cl_gameui.c | 18 +-- engine/client/cl_main.c | 38 +++-- engine/client/cl_parse.c | 56 +++----- engine/client/cl_remap.c | 4 +- engine/client/gl_backend.c | 6 +- engine/client/gl_decals.c | 2 +- engine/client/gl_image.c | 24 ++-- engine/client/gl_rmisc.c | 2 +- engine/client/gl_studio.c | 208 +++------------------------ engine/client/gl_warp.c | 30 ++-- engine/client/s_load.c | 4 +- engine/common/avikit.c | 2 +- engine/common/cmd.c | 4 +- engine/common/common.c | 207 ++++++++++++++++++++------- engine/common/common.h | 18 ++- engine/common/con_utils.c | 66 ++++----- engine/common/console.c | 56 +++++++- engine/common/crclib.c | 6 +- engine/common/filesystem.c | 226 +++++------------------------- engine/common/host.c | 43 ++---- engine/common/hpak.c | 56 ++++---- engine/common/imagelib/img_main.c | 8 +- engine/common/library.c | 32 ++--- engine/common/library.h | 12 +- engine/common/mod_bmodel.c | 30 ++-- engine/common/mod_local.h | 5 +- engine/common/mod_studio.c | 185 +++++++++++++++++++++++- engine/common/model.c | 45 ++---- engine/common/net_chan.c | 2 +- engine/common/net_ws.c | 21 +-- engine/common/protocol.h | 2 +- engine/common/soundlib/snd_main.c | 8 +- engine/engine.dsp | 4 + engine/server/server.h | 8 +- engine/server/sv_client.c | 173 ++++++++++------------- engine/server/sv_cmds.c | 134 ++---------------- engine/server/sv_frame.c | 1 - engine/server/sv_game.c | 175 ++++++++++++++++------- engine/server/sv_init.c | 91 +++++------- engine/server/sv_log.c | 8 +- engine/server/sv_main.c | 40 ++---- engine/server/sv_phys.c | 5 +- engine/server/sv_save.c | 6 +- 45 files changed, 981 insertions(+), 1141 deletions(-) diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index fcb5c003..3f7ff2c7 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -130,7 +130,7 @@ void CL_StartupDemoHeader( void ) return; } - MsgDev( D_INFO, "Spooling demo header.\n" ); + Con_Printf( "Spooling demo header.\n" ); } /* @@ -353,7 +353,7 @@ void CL_WriteDemoHeader( const char *name ) long savepos; long curpos; - MsgDev( D_INFO, "recording to %s.\n", name ); + Con_Printf( "recording to %s.\n", name ); cls.demofile = FS_Open( name, "wb", false ); cls.demotime = 0.0; @@ -479,9 +479,7 @@ void CL_StopRecord( void ) demo.header.host_fps = 0.0; frames = cls.td_lastframe - cls.td_startframe; - - Msg( "Completed demo\n" ); - MsgDev( D_INFO, "Recording time: %02d:%02d, frames %i\n", (int)(cls.demotime / 60.0f ), (int)fmod( cls.demotime, 60.0f ), frames ); + Con_Printf( "Completed demo\nRecording time: %02d:%02d, frames %i\n", (int)(cls.demotime / 60.0f), (int)fmod(cls.demotime, 60.0f), frames ); cls.demotime = 0.0; } @@ -1094,7 +1092,7 @@ Called when a demo finishes */ qboolean CL_NextDemo( void ) { - string str; + char str[MAX_QPATH]; if( cls.demonum == -1 ) return false; // don't play demos @@ -1105,14 +1103,13 @@ qboolean CL_NextDemo( void ) cls.demonum = 0; if( !cls.demos[cls.demonum][0] ) { - MsgDev( D_INFO, "no demos listed with startdemos\n" ); + Con_Printf( "no demos listed with startdemos\n" ); cls.demonum = -1; return false; } } Q_snprintf( str, MAX_STRING, "playdemo %s\n", cls.demos[cls.demonum] ); - Cbuf_InsertText( str ); cls.demonum++; @@ -1393,7 +1390,7 @@ void CL_StartDemos_f( void ) if( cls.key_dest != key_menu ) { - MsgDev( D_INFO, "startdemos is not valid from the console\n" ); + Con_Printf( "'startdemos' is not valid from the console\n" ); return; } @@ -1404,7 +1401,7 @@ void CL_StartDemos_f( void ) c = MAX_DEMOS; } - MsgDev( D_INFO, "%i demo%s in loop\n", c, (c > 1) ? "s" : "" ); + Con_Printf( "%i demo%s in loop\n", c, (c > 1) ? "s" : "" ); for( i = 1; i < c + 1; i++ ) Q_strncpy( cls.demos[i-1], Cmd_Argv( i ), sizeof( cls.demos[0] )); @@ -1430,7 +1427,7 @@ void CL_Demos_f( void ) { if( cls.key_dest != key_menu ) { - MsgDev( D_INFO, "demos is not valid from the console\n" ); + Con_Printf( "'demos' is not valid from the console\n" ); return; } diff --git a/engine/client/cl_game.c b/engine/client/cl_game.c index 4d01a740..e834b161 100644 --- a/engine/client/cl_game.c +++ b/engine/client/cl_game.c @@ -333,9 +333,12 @@ print centerscreen message */ void CL_CenterPrint( const char *text, float y ) { - char *s; - int width = 0; int length = 0; + int width = 0; + char *s; + + if( !COM_CheckString( text )) + return; clgame.centerPrint.lines = 1; clgame.centerPrint.totalWidth = 0; @@ -1437,7 +1440,7 @@ static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount ) if( piCount ) *piCount = 0; if( !clgame.itemspath[0] ) // typically it's sprites\*.txt - FS_ExtractFilePath( psz, clgame.itemspath ); + COM_ExtractFilePath( psz, clgame.itemspath ); afile = FS_LoadFile( psz, NULL, false ); if( !afile ) return NULL; @@ -1839,9 +1842,7 @@ prints directly into console (can skip notify) */ static void pfnConsolePrint( const char *string ) { - if( !string || !*string ) return; - if( *string != 1 ) Con_Print( (char *)string ); // show notify - else Con_NPrintf( 0, (char *)string + 1 ); // skip notify + Con_Printf( "%s", string ); } /* @@ -1854,7 +1855,6 @@ like trigger_multiple message in q1 */ static void pfnCenterPrint( const char *string ) { - if( !string || !*string ) return; // someone stupid joke CL_CenterPrint( string, 0.25f ); } @@ -3707,7 +3707,7 @@ void CL_UnloadProgs( void ) Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "host_clientloaded", "0", FCVAR_READ_ONLY ); - Com_FreeLibrary( clgame.hInstance ); + COM_FreeLibrary( clgame.hInstance ); Mem_FreePool( &cls.mempool ); Mem_FreePool( &clgame.mempool ); memset( &clgame, 0, sizeof( clgame )); @@ -3732,15 +3732,15 @@ qboolean CL_LoadProgs( const char *name ) clgame.mempool = Mem_AllocPool( "Client Edicts Zone" ); clgame.entities = NULL; - clgame.hInstance = Com_LoadLibrary( name, false ); + clgame.hInstance = COM_LoadLibrary( name, false ); if( !clgame.hInstance ) return false; // clear exports for( func = cdll_exports; func && func->name; func++ ) *func->func = NULL; - // trying to get single export named 'F' - if(( GetClientAPI = (void *)Com_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL ) + // trying to get single export + if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL ) { MsgDev( D_NOTE, "CL_LoadProgs: found single callback export\n" ); @@ -3765,13 +3765,13 @@ qboolean CL_LoadProgs( const char *name ) continue; // already get through 'F' // functions are cleared before all the extensions are evaluated - if(!( *func->func = (void *)Com_GetProcAddress( clgame.hInstance, func->name ))) + if(( *func->func = (void *)COM_GetProcAddress( clgame.hInstance, func->name )) == NULL ) { MsgDev( D_NOTE, "CL_LoadProgs: failed to get address of %s proc\n", func->name ); if( critical_exports ) { - Com_FreeLibrary( clgame.hInstance ); + COM_FreeLibrary( clgame.hInstance ); clgame.hInstance = NULL; return false; } @@ -3793,13 +3793,13 @@ qboolean CL_LoadProgs( const char *name ) // functions are cleared before all the extensions are evaluated // NOTE: new exports can be missed without stop the engine - if(!( *func->func = (void *)Com_GetProcAddress( clgame.hInstance, func->name ))) - MsgDev( D_NOTE, "CL_LoadProgs: failed to get address of %s proc\n", func->name ); + if(( *func->func = (void *)COM_GetProcAddress( clgame.hInstance, func->name )) == NULL ) + MsgDev( D_NOTE, "CL_LoadProgs: failed to get address of %s proc\n", func->name ); } if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION )) { - Com_FreeLibrary( clgame.hInstance ); + COM_FreeLibrary( clgame.hInstance ); MsgDev( D_NOTE, "CL_LoadProgs: can't init client API\n" ); clgame.hInstance = NULL; return false; diff --git a/engine/client/cl_gameui.c b/engine/client/cl_gameui.c index 871b2f8b..dbf93976 100644 --- a/engine/client/cl_gameui.c +++ b/engine/client/cl_gameui.c @@ -140,7 +140,7 @@ static void UI_DrawLogo( const char *filename, float x, float y, float width, fl // run cinematic if not Q_snprintf( path, sizeof( path ), "media/%s", filename ); - FS_DefaultExtension( path, ".avi" ); + COM_DefaultExtension( path, ".avi" ); fullpath = FS_GetDiskPath( path, false ); if( FS_FileExists( path, false ) && !fullpath ) @@ -841,9 +841,9 @@ int pfnCheckGameDll( void ) if( SV_Initialized( )) return true; - if(( hInst = Com_LoadLibrary( GI->game_dll, true )) != NULL ) + if(( hInst = COM_LoadLibrary( GI->game_dll, true )) != NULL ) { - Com_FreeLibrary( hInst ); + COM_FreeLibrary( hInst ); return true; } return false; @@ -988,7 +988,7 @@ void UI_UnloadProgs( void ) Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY ); - Com_FreeLibrary( gameui.hInstance ); + COM_FreeLibrary( gameui.hInstance ); Mem_FreePool( &gameui.mempool ); memset( &gameui, 0, sizeof( gameui )); @@ -1007,11 +1007,11 @@ qboolean UI_LoadProgs( void ) // setup globals gameui.globals = &gpGlobals; - if(!( gameui.hInstance = Com_LoadLibrary( va( "%s/menu.dll", GI->dll_path ), false ))) + if(!( gameui.hInstance = COM_LoadLibrary( va( "%s/menu.dll", GI->dll_path ), false ))) { FS_AllowDirectPaths( true ); - if(!( gameui.hInstance = Com_LoadLibrary( "../menu.dll", false ))) + if(!( gameui.hInstance = COM_LoadLibrary( "../menu.dll", false ))) { FS_AllowDirectPaths( false ); return false; @@ -1020,9 +1020,9 @@ qboolean UI_LoadProgs( void ) FS_AllowDirectPaths( false ); } - if(!( GetMenuAPI = (MENUAPI)Com_GetProcAddress( gameui.hInstance, "GetMenuAPI" ))) + if(!( GetMenuAPI = (MENUAPI)COM_GetProcAddress( gameui.hInstance, "GetMenuAPI" ))) { - Com_FreeLibrary( gameui.hInstance ); + COM_FreeLibrary( gameui.hInstance ); MsgDev( D_NOTE, "UI_LoadProgs: can't init menu API\n" ); gameui.hInstance = NULL; return false; @@ -1035,7 +1035,7 @@ qboolean UI_LoadProgs( void ) if( !GetMenuAPI( &gameui.dllFuncs, &gpEngfuncs, gameui.globals )) { - Com_FreeLibrary( gameui.hInstance ); + COM_FreeLibrary( gameui.hInstance ); MsgDev( D_NOTE, "UI_LoadProgs: can't init menu API\n" ); Mem_FreePool( &gameui.mempool ); gameui.hInstance = NULL; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 3c0b00cc..c19b76c3 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -195,13 +195,13 @@ void CL_SignonReply( void ) { case 1: // g-cont. my favorite message :-) - MsgDev( D_INFO, "CL_SignonReply: %i\n", cls.signon ); + Con_Printf( "CL_SignonReply: %i\n", cls.signon ); CL_ServerCommand( true, "begin" ); if( host.developer >= D_REPORT ) Mem_PrintStats(); break; case 2: - MsgDev( D_INFO, "client connected at %.2f sec\n", Sys_DoubleTime() - cls.timestart ); + Con_Printf( "client connected at %.2f sec\n", Sys_DoubleTime() - cls.timestart ); if( cl.proxy_redirect && !cls.spectator ) CL_Disconnect(); cl.proxy_redirect = false; @@ -311,13 +311,13 @@ void CL_ComputeClientInterpolationAmount( usercmd_t *cmd ) if(( interpolation_msec + 1 ) < min_interp ) { - MsgDev( D_INFO, "ex_interp forced up to %i msec\n", interpolation_msec ); + Con_Printf( "ex_interp forced up to %i msec\n", interpolation_msec ); interpolation_msec = min_interp; forced = true; } else if(( interpolation_msec - 1 ) > max_interp ) { - MsgDev( D_INFO, "ex_interp forced down to %i msec\n", interpolation_msec ); + Con_Printf( "ex_interp forced down to %i msec\n", interpolation_msec ); interpolation_msec = max_interp; forced = true; } @@ -882,7 +882,7 @@ void CL_BeginUpload_f( void ) if( Q_strlen( name ) != 36 || Q_strnicmp( name, "!MD5", 4 )) { - MsgDev( D_INFO, "Ingoring upload of non-customization\n" ); + Con_Printf( "Ingoring upload of non-customization\n" ); return; } @@ -1006,7 +1006,7 @@ void CL_SendConnectPacket( void ) if( !NET_StringToAdr( cls.servername, &adr )) { - MsgDev( D_INFO, "CL_SendConnectPacket: bad server address\n"); + Con_Printf( "CL_SendConnectPacket: bad server address\n"); cls.connect_time = 0; return; } @@ -1090,13 +1090,8 @@ void CL_Connect_f( void ) Q_strncpy( server, Cmd_Argv( 1 ), sizeof( server )); - if( Host_ServerState()) - { - // if running a local server, kill it and reissue - Q_strncpy( host.finalmsg, "Server quit", MAX_STRING ); - SV_Shutdown( false ); - } - + // if running a local server, kill it and reissue + if( SV_Active( )) Host_ShutdownServer(); NET_Config( true ); // allow remote Msg( "server %s\n", server ); @@ -1337,7 +1332,7 @@ void CL_LocalServers_f( void ) { netadr_t adr; - MsgDev( D_INFO, "Scanning for servers on the local network area...\n" ); + Con_Printf( "Scanning for servers on the local network area...\n" ); NET_Config( true ); // allow remote // send a broadcast packet @@ -1357,11 +1352,11 @@ void CL_InternetServers_f( void ) netadr_t adr; char fullquery[512] = "1\xFF" "0.0.0.0:0\0" "\\gamedir\\"; - MsgDev( D_INFO, "Scanning for servers on the internet area...\n" ); + Con_Printf( "Scanning for servers on the internet area...\n" ); NET_Config( true ); // allow remote if( !NET_StringToAdr( MASTERSERVER_ADR, &adr ) ) - MsgDev( D_INFO, "Can't resolve adr: %s\n", MASTERSERVER_ADR ); + MsgDev( D_ERROR, "Can't resolve adr: %s\n", MASTERSERVER_ADR ); Q_strcpy( &fullquery[22], GI->gamedir ); @@ -1537,7 +1532,7 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg ) CL_FixupColorStringsForInfoString( s, infostring ); // more info about servers - MsgDev( D_INFO, "Server: %s, Game: %s\n", NET_AdrToString( from ), Info_ValueForKey( infostring, "gamedir" )); + Con_Printf( "Server: %s, Game: %s\n", NET_AdrToString( from ), Info_ValueForKey( infostring, "gamedir" )); UI_AddServerToList( from, infostring ); } @@ -1790,7 +1785,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg ) { if( cls.state == ca_connected ) { - MsgDev( D_INFO, "dup connect received. ignored\n"); + MsgDev( D_ERROR, "dup connect received. ignored\n"); return; } @@ -1875,7 +1870,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg ) if( nr->timeout <= host.realtime ) SetBits( nr->resp.error, NET_ERROR_TIMEOUT ); - MsgDev( D_INFO, "serverlist call: %s\n", NET_AdrToString( from )); + Con_Printf( "serverlist call: %s\n", NET_AdrToString( from )); nr->pfnFunc( &nr->resp ); // throw the list, now it will be stored in user area @@ -2074,7 +2069,7 @@ A file has been received via the fragmentation/reassembly layer, put it in the r void CL_ProcessFile( qboolean successfully_received, const char *filename ) { if( successfully_received ) - MsgDev( D_INFO, "received %s\n", filename ); + Con_Printf( "received %s\n", filename ); else MsgDev( D_WARN, "failed to download %s", filename ); } @@ -2387,7 +2382,6 @@ void CL_InitLocal( void ) Cmd_AddCommand ("drop", NULL, "drop current/specified item or weapon" ); Cmd_AddCommand ("gametitle", NULL, "show game logo" ); Cmd_AddCommand ("god", NULL, "enable godmode" ); - Cmd_AddCommand ("fly", NULL, "enable fly mode" ); Cmd_AddCommand ("fov", NULL, "set client field of view" ); Cmd_AddCommand ("log", NULL, "logging server events" ); @@ -2612,7 +2606,7 @@ void CL_Shutdown( void ) if( !cls.initialized ) return; cls.initialized = false; - MsgDev( D_INFO, "CL_Shutdown()\n" ); + Con_Printf( "CL_Shutdown()\n" ); Host_WriteOpenGLConfig (); Host_WriteVideoConfig (); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 27b31a41..98a6c49d 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -33,7 +33,7 @@ const char *svc_strings[svc_lastmsg+1] = "svc_nop", "svc_disconnect", "svc_event", - "svc_changing", + "svc_version", "svc_setview", "svc_sound", "svc_time", @@ -173,7 +173,7 @@ void CL_WriteErrorMessage( int current_count, sizebuf_t *msg ) FS_Write( fp, MSG_GetData( msg ), MSG_GetMaxBytes( msg )); FS_Close( fp ); - MsgDev( D_INFO, "Wrote erroneous message to %s\n", buffer_file ); + Con_Printf( "Wrote erroneous message to %s\n", buffer_file ); } /* @@ -185,9 +185,9 @@ list last 32 messages for debugging net troubleshooting */ void CL_WriteMessageHistory( void ) { - int i, thecmd; oldcmd_t *old, *failcommand; sizebuf_t *msg = &net_message; + int i, thecmd; if( !cls.initialized || cls.state == ca_disconnected ) return; @@ -195,7 +195,7 @@ void CL_WriteMessageHistory( void ) if( !cls_message_debug.parsing ) return; - MsgDev( D_INFO, "Last %i messages parsed.\n", MSG_COUNT ); + Con_Printf( "Last %i messages parsed.\n", MSG_COUNT ); // finish here thecmd = cls_message_debug.currentcmd - 1; @@ -205,19 +205,14 @@ void CL_WriteMessageHistory( void ) { thecmd &= MSG_MASK; old = &cls_message_debug.oldcmd[thecmd]; - - MsgDev( D_INFO,"%i %04i %s\n", old->frame_number, old->starting_offset, CL_MsgInfo( old->command )); - + Con_Printf( "%i %04i %s\n", old->frame_number, old->starting_offset, CL_MsgInfo( old->command )); thecmd++; } failcommand = &cls_message_debug.oldcmd[thecmd]; - MsgDev( D_INFO, "BAD: %3i:%s\n", MSG_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command )); - - if( host.developer >= 3 ) - { + Con_Printf( "BAD: %3i:%s\n", MSG_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command )); + if( host.developer >= 2 ) CL_WriteErrorMessage( MSG_GetNumBytesRead( msg ) - 1, msg ); - } cls_message_debug.parsing = false; } @@ -743,6 +738,7 @@ void CL_ParseServerData( sizebuf_t *msg ) qboolean background; MsgDev( D_NOTE, "Serverdata packet received.\n" ); + cls.timestart = Sys_DoubleTime(); cls.demowaiting = false; // server is changed cls.state = ca_connected; @@ -1204,7 +1200,7 @@ void CL_ParseRestore( sizebuf_t *msg ) for( i = 0; i < mapCount; i++ ) { pMapName = MSG_ReadString( msg ); - MsgDev( D_INFO, "Loading decals from %s\n", pMapName ); + Con_Printf( "Loading decals from %s\n", pMapName ); } } @@ -1503,7 +1499,7 @@ void CL_RegisterResources ( sizebuf_t *msg ) if( cls.state != ca_disconnected ) { - MsgDev( D_INFO, "Setting up renderer...\n" ); + Con_Printf( "Setting up renderer...\n" ); // load tempent sprites (glowshell, muzzleflashes etc) CL_LoadClientSprites (); @@ -2277,30 +2273,10 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message ) CL_ParseEvent( msg ); cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart; break; - case svc_changing: - if( MSG_ReadOneBit( msg )) - { - cls.changelevel = true; - S_StopAllSounds( true ); - - if( cls.demoplayback ) - { - SCR_BeginLoadingPlaque( cl.background ); - cls.changedemo = true; - } - } - else MsgDev( D_INFO, "Server disconnected, reconnecting\n" ); - - CL_ClearState (); - CL_InitEdicts (); // re-arrange edicts - - if( cls.demoplayback ) - { - cl.background = (cls.demonum != -1) ? true : false; - cls.state = ca_connected; - } - else cls.state = ca_connecting; - cls.connect_time = MAX_HEARTBEAT; // CL_CheckForResend() will fire immediately + case svc_version: + param1 = MSG_ReadLong( msg ); + if( param1 != PROTOCOL_VERSION ) + Host_Error( "Server is protocol %i instead of %i\n", param1, PROTOCOL_VERSION ); break; case svc_setview: CL_ParseViewEntity( msg ); @@ -2313,7 +2289,9 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message ) CL_ParseServerTime( msg ); break; case svc_print: - MsgDev( D_INFO, "^5%s", MSG_ReadString( msg )); + if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE )) + MsgDev( D_INFO, "%s", MSG_ReadString( msg )); + else MsgDev( D_INFO, "^5%s", MSG_ReadString( msg )); break; case svc_stufftext: Cbuf_AddText( MSG_ReadString( msg )); diff --git a/engine/client/cl_remap.c b/engine/client/cl_remap.c index c3d4f3e8..2324bf39 100644 --- a/engine/client/cl_remap.c +++ b/engine/client/cl_remap.c @@ -154,8 +154,8 @@ void CL_UpdateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor // build name of original texture Q_strncpy( mdlname, RI.currentmodel->name, sizeof( mdlname )); - FS_FileBase( ptexture->name, name ); - FS_StripExtension( mdlname ); + COM_FileBase( ptexture->name, name ); + COM_StripExtension( mdlname ); Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name ); index = GL_FindTexture( texname ); diff --git a/engine/client/gl_backend.c b/engine/client/gl_backend.c index 7e8714ea..215339f6 100644 --- a/engine/client/gl_backend.c +++ b/engine/client/gl_backend.c @@ -596,8 +596,8 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo // make sure what we have right extension Q_strncpy( basename, base, MAX_STRING ); - FS_StripExtension( basename ); - FS_DefaultExtension( basename, ".tga" ); + COM_StripExtension( basename ); + COM_DefaultExtension( basename, ".tga" ); // write image as 6 sides result = FS_SaveImage( basename, r_shot ); @@ -706,7 +706,7 @@ rebuild_page: if( FBitSet( image->flags, TF_DEPTHMAP ) && !FBitSet( image->flags, TF_NOCOMPARE )) pglTexParameteri( image->target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB ); - FS_FileBase( image->name, shortname ); + COM_FileBase( image->name, shortname ); if( Q_strlen( shortname ) > 18 ) { // cutoff too long names, it looks ugly diff --git a/engine/client/gl_decals.c b/engine/client/gl_decals.c index 580a568b..8c7f43d6 100644 --- a/engine/client/gl_decals.c +++ b/engine/client/gl_decals.c @@ -1169,7 +1169,7 @@ int R_CreateDecalList( decallist_t *pList ) pList[total].scale = decal->scale; R_DecalUnProject( decal, &pList[total] ); - FS_FileBase( R_GetTexture( decal->texture )->name, pList[total].name ); + COM_FileBase( R_GetTexture( decal->texture )->name, pList[total].name ); // check to see if the decal should be added total = DecalListAdd( pList, total ); diff --git a/engine/client/gl_image.c b/engine/client/gl_image.c index 9705a1c6..702d069e 100644 --- a/engine/client/gl_image.c +++ b/engine/client/gl_image.c @@ -1310,7 +1310,7 @@ int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags, i } // see if already loaded - hash = Com_HashKey( name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( name, TEXTURES_HASH_SIZE ); for( tex = r_texturesHashTable[hash]; tex != NULL; tex = tex->nextHash ) { @@ -1370,7 +1370,7 @@ int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags, i FS_FreeImage( pic ); // release source texture // add to hash table - hash = Com_HashKey( tex->name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( tex->name, TEXTURES_HASH_SIZE ); tex->nextHash = r_texturesHashTable[hash]; r_texturesHashTable[hash] = tex; @@ -1406,7 +1406,7 @@ int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter ) // create complexname from layer names for( i = 0; i < numLayers; i++ ) { - FS_FileBase( names[i], basename ); + COM_FileBase( names[i], basename ); Q_strncat( name, va( "%s", basename ), sizeof( name )); if( i != ( numLayers - 1 )) Q_strncat( name, "|", sizeof( name )); } @@ -1420,7 +1420,7 @@ int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter ) } // see if already loaded - hash = Com_HashKey( name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( name, TEXTURES_HASH_SIZE ); for( tex = r_texturesHashTable[hash]; tex != NULL; tex = tex->nextHash ) { @@ -1541,7 +1541,7 @@ int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter ) FS_FreeImage( pic ); // release source texture // add to hash table - hash = Com_HashKey( tex->name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( tex->name, TEXTURES_HASH_SIZE ); tex->nextHash = r_texturesHashTable[hash]; r_texturesHashTable[hash] = tex; @@ -1569,7 +1569,7 @@ int GL_LoadTextureInternal( const char *name, rgbdata_t *pic, texFlags_t flags, } // see if already loaded - hash = Com_HashKey( name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( name, TEXTURES_HASH_SIZE ); for( tex = r_texturesHashTable[hash]; tex != NULL; tex = tex->nextHash ) { @@ -1604,7 +1604,7 @@ int GL_LoadTextureInternal( const char *name, rgbdata_t *pic, texFlags_t flags, } tex = &r_textures[i]; - hash = Com_HashKey( name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( name, TEXTURES_HASH_SIZE ); Q_strncpy( tex->name, name, sizeof( tex->name )); tex->texnum = i; // texnum is used for fast acess into r_textures array too tex->flags = flags; @@ -1626,7 +1626,7 @@ int GL_LoadTextureInternal( const char *name, rgbdata_t *pic, texFlags_t flags, if( !update ) { // add to hash table - hash = Com_HashKey( tex->name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( tex->name, TEXTURES_HASH_SIZE ); tex->nextHash = r_texturesHashTable[hash]; r_texturesHashTable[hash] = tex; } @@ -1789,7 +1789,7 @@ int GL_FindTexture( const char *name ) } // see if already loaded - hash = Com_HashKey( name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( name, TEXTURES_HASH_SIZE ); for( tex = r_texturesHashTable[hash]; tex != NULL; tex = tex->nextHash ) { @@ -1822,7 +1822,7 @@ void GL_FreeImage( const char *name ) } // see if already loaded - hash = Com_HashKey( name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( name, TEXTURES_HASH_SIZE ); for( tex = r_texturesHashTable[hash]; tex != NULL; tex = tex->nextHash ) { @@ -1870,7 +1870,7 @@ void R_FreeImage( gltexture_t *image ) } // remove from hash table - hash = Com_HashKey( image->name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( image->name, TEXTURES_HASH_SIZE ); prev = &r_texturesHashTable[hash]; while( 1 ) @@ -2729,7 +2729,7 @@ void R_InitImages( void ) // create unused 0-entry Q_strncpy( r_textures->name, "*unused*", sizeof( r_textures->name )); - hash = Com_HashKey( r_textures->name, TEXTURES_HASH_SIZE ); + hash = COM_HashKey( r_textures->name, TEXTURES_HASH_SIZE ); r_textures->nextHash = r_texturesHashTable[hash]; r_texturesHashTable[hash] = r_textures; r_numTextures = 1; diff --git a/engine/client/gl_rmisc.c b/engine/client/gl_rmisc.c index b1299c9b..0060505d 100644 --- a/engine/client/gl_rmisc.c +++ b/engine/client/gl_rmisc.c @@ -455,7 +455,7 @@ void R_NewMap( void ) string mapname, filepath; Q_strncpy( mapname, cl.worldmodel->name, sizeof( mapname )); - FS_StripExtension( mapname ); + COM_StripExtension( mapname ); Q_sprintf( filepath, "%s_detail.txt", mapname ); R_ParseDetailTextures( filepath ); diff --git a/engine/client/gl_studio.c b/engine/client/gl_studio.c index e5134ddb..9c7b3878 100644 --- a/engine/client/gl_studio.c +++ b/engine/client/gl_studio.c @@ -147,24 +147,6 @@ void R_StudioInit( void ) m_fDoRemap = false; } -/* -=============== -R_StudioTexName - -extract texture filename from modelname -=============== -*/ -const char *R_StudioTexName( model_t *mod ) -{ - static char texname[64]; - - Q_strncpy( texname, mod->name, sizeof( texname )); - FS_StripExtension( texname ); - Q_strncat( texname, "T.mdl", sizeof( texname )); - - return texname; -} - /* ================ R_GetEntityRenderMode @@ -194,32 +176,6 @@ int R_GetEntityRenderMode( cl_entity_t *ent ) return ent->curstate.rendermode; } -/* -================ -R_StudioBodyVariations - -calc studio body variations -================ -*/ -static int R_StudioBodyVariations( model_t *mod ) -{ - studiohdr_t *pstudiohdr; - mstudiobodyparts_t *pbodypart; - int i, count = 1; - - pstudiohdr = (studiohdr_t *)Mod_StudioExtradata( mod ); - if( !pstudiohdr ) return 0; - - pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex); - - // each body part has nummodels variations so there are as many total variations as there - // are in a matrix of each part by each other part - for( i = 0; i < pstudiohdr->numbodyparts; i++ ) - count = count * pbodypart[i].nummodels; - - return count; -} - /* ================ R_StudioSetupTimings @@ -821,8 +777,8 @@ void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstud { string filepath, modelname, modelpath; - FS_FileBase( m_pSubModel->name, modelname ); - FS_ExtractFilePath( m_pSubModel->name, modelpath ); + COM_FileBase( m_pSubModel->name, modelname ); + COM_ExtractFilePath( m_pSubModel->name, modelpath ); // NOTE: here we build real sub-animation filename because stupid user may rename model without recompile Q_snprintf( filepath, sizeof( filepath ), "%s/%s%i%i.mdl", modelpath, modelname, pseqdesc->seqgroup / 10, pseqdesc->seqgroup % 10 ); @@ -3801,8 +3757,8 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture } Q_strncpy( mdlname, mod->name, sizeof( mdlname )); - FS_FileBase( ptexture->name, name ); - FS_StripExtension( mdlname ); + COM_FileBase( ptexture->name, name ); + COM_StripExtension( mdlname ); // loading texture filter for studiomodel if( !FBitSet( ptexture->flags, STUDIO_NF_COLORMAP )) @@ -3824,27 +3780,27 @@ static void R_StudioLoadTexture( model_t *mod, studiohdr_t *phdr, mstudiotexture if( !ptexture->index ) { - MsgDev( D_WARN, "%s has null texture %s\n", mod->name, ptexture->name ); ptexture->index = tr.defaultTexture; } - else + else if( tx ) { // duplicate texnum for easy acess - if( tx ) tx->gl_texturenum = ptexture->index; + tx->gl_texturenum = ptexture->index; } } /* ================= -R_StudioLoadTextures +Mod_StudioLoadTextures ================= */ -void R_StudioLoadTextures( model_t *mod, studiohdr_t *phdr ) +void Mod_StudioLoadTextures( model_t *mod, void *data ) { + studiohdr_t *phdr = (studiohdr_t *)data; mstudiotexture_t *ptexture; int i; - if( host.type == HOST_DEDICATED ) + if( !phdr || host.type == HOST_DEDICATED ) return; ptexture = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex); @@ -3857,157 +3813,27 @@ void R_StudioLoadTextures( model_t *mod, studiohdr_t *phdr ) /* ================= -R_StudioLoadHeader +Mod_StudioLoadTextures ================= */ -studiohdr_t *R_StudioLoadHeader( model_t *mod, const void *buffer ) +void Mod_StudioUnloadTextures( void *data ) { - byte *pin; - studiohdr_t *phdr; - int i; - - if( !buffer ) return NULL; - - pin = (byte *)buffer; - phdr = (studiohdr_t *)pin; - i = phdr->version; - - if( i != STUDIO_VERSION ) - { - MsgDev( D_ERROR, "%s has wrong version number (%i should be %i)\n", mod->name, i, STUDIO_VERSION ); - return NULL; - } - - return (studiohdr_t *)buffer; -} - -/* -================= -Mod_LoadStudioModel -================= -*/ -void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ) -{ - studiohdr_t *phdr; - - if( loaded ) *loaded = false; - loadmodel->mempool = Mem_AllocPool( va( "^2%s^7", loadmodel->name )); - loadmodel->type = mod_studio; - - phdr = R_StudioLoadHeader( mod, buffer ); - if( !phdr ) return; // bad model - - if( phdr->numtextures == 0 ) - { - studiohdr_t *thdr; - byte *in, *out; - void *buffer2 = NULL; - size_t size1, size2; - - buffer2 = FS_LoadFile( R_StudioTexName( mod ), NULL, false ); - thdr = R_StudioLoadHeader( mod, buffer2 ); - - if( !thdr ) - { - MsgDev( D_WARN, "Mod_LoadStudioModel: %s missing textures file\n", mod->name ); - if( buffer2 ) Mem_Free( buffer2 ); - } - else - { - R_StudioLoadTextures( mod, thdr ); - - // give space for textures and skinrefs - size1 = thdr->numtextures * sizeof( mstudiotexture_t ); - size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short ); - mod->cache.data = Mem_Alloc( loadmodel->mempool, phdr->length + size1 + size2 ); - memcpy( loadmodel->cache.data, buffer, phdr->length ); // copy main mdl buffer - phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr - phdr->numskinfamilies = thdr->numskinfamilies; - phdr->numtextures = thdr->numtextures; - phdr->numskinref = thdr->numskinref; - phdr->textureindex = phdr->length; - phdr->skinindex = phdr->textureindex + size1; - - in = (byte *)thdr + thdr->textureindex; - out = (byte *)phdr + phdr->textureindex; - memcpy( out, in, size1 + size2 ); // copy textures + skinrefs - phdr->length += size1 + size2; - Mem_Free( buffer2 ); // release T.mdl - } - } - else - { - // NOTE: don't modify source buffer because it's used for CRC computing - loadmodel->cache.data = Mem_Alloc( loadmodel->mempool, phdr->length ); - memcpy( loadmodel->cache.data, buffer, phdr->length ); - phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr - R_StudioLoadTextures( mod, phdr ); - - // NOTE: we wan't keep raw textures in memory. just cutoff model pointer above texture base - loadmodel->cache.data = Mem_Realloc( loadmodel->mempool, loadmodel->cache.data, phdr->texturedataindex ); - phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr - phdr->length = phdr->texturedataindex; // update model size - } - - // setup bounding box - if( !VectorCompare( vec3_origin, phdr->bbmin )) - { - // clipping bounding box - VectorCopy( phdr->bbmin, loadmodel->mins ); - VectorCopy( phdr->bbmax, loadmodel->maxs ); - } - else if( !VectorCompare( vec3_origin, phdr->min )) - { - // movement bounding box - VectorCopy( phdr->min, loadmodel->mins ); - VectorCopy( phdr->max, loadmodel->maxs ); - } - else - { - // well compute bounds from vertices and round to nearest even values - Mod_StudioComputeBounds( phdr, loadmodel->mins, loadmodel->maxs, true ); - RoundUpHullSize( loadmodel->mins ); - RoundUpHullSize( loadmodel->maxs ); - } - - loadmodel->numframes = R_StudioBodyVariations( loadmodel ); - loadmodel->radius = RadiusFromBounds( loadmodel->mins, loadmodel->maxs ); - loadmodel->flags = phdr->flags; // copy header flags - - if( loaded ) *loaded = true; -} - -/* -================= -Mod_UnloadStudioModel -================= -*/ -void Mod_UnloadStudioModel( model_t *mod ) -{ - studiohdr_t *pstudio; + studiohdr_t *phdr = (studiohdr_t *)data; mstudiotexture_t *ptexture; int i; - Assert( mod != NULL ); + if( !phdr || host.type == HOST_DEDICATED ) + return; - if( mod->type != mod_studio ) - return; // not a studio - - pstudio = mod->cache.data; - if( !pstudio ) return; // already freed - - ptexture = (mstudiotexture_t *)(((byte *)pstudio) + pstudio->textureindex); + ptexture = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex); // release all textures - for( i = 0; i < pstudio->numtextures; i++ ) + for( i = 0; i < phdr->numtextures; i++ ) { if( ptexture[i].index == tr.defaultTexture ) continue; GL_FreeTexture( ptexture[i].index ); } - - Mem_FreePool( &mod->mempool ); - memset( mod, 0, sizeof( *mod )); } static engine_studio_api_t gStudioAPI = diff --git a/engine/client/gl_warp.c b/engine/client/gl_warp.c index f106a6d2..a4cecdfb 100644 --- a/engine/client/gl_warp.c +++ b/engine/client/gl_warp.c @@ -449,7 +449,7 @@ void R_SetupSky( const char *skyboxname ) } Q_snprintf( loadname, sizeof( loadname ), "gfx/env/%s", skyboxname ); - FS_StripExtension( loadname ); + COM_StripExtension( loadname ); // kill the underline suffix to find them manually later if( loadname[Q_strlen( loadname ) - 1] == '_' ) @@ -459,40 +459,34 @@ void R_SetupSky( const char *skyboxname ) // to prevent infinite recursion if default skybox was missed if( result == SKYBOX_MISSED && Q_stricmp( loadname, "gfx/env/desert" )) { - MsgDev( D_ERROR, "R_SetupSky: missed or incomplete skybox '%s'\n", skyboxname ); + MsgDev( D_ERROR, "missed or incomplete skybox '%s'\n", skyboxname ); R_SetupSky( "desert" ); // force to default return; } // release old skybox R_UnloadSkybox(); + Con_DPrintf( "SKY: " ); - if( result == SKYBOX_HLSTYLE ) + for( i = 0; i < 6; i++ ) { - for( i = 0; i < 6; i++ ) - { + if( result == SKYBOX_HLSTYLE ) Q_snprintf( sidename, sizeof( sidename ), "%s%s", loadname, r_skyBoxSuffix[i] ); - tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY, NULL ); - if( !tr.skyboxTextures[i] ) break; - } - } - else if( result == SKYBOX_Q1STYLE ) - { - for( i = 0; i < 6; i++ ) - { - Q_snprintf( sidename, sizeof( sidename ), "%s_%s", loadname, r_skyBoxSuffix[i] ); - tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY, NULL ); - if( !tr.skyboxTextures[i] ) break; - } + else Q_snprintf( sidename, sizeof( sidename ), "%s_%s", loadname, r_skyBoxSuffix[i] ); + + tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY, NULL ); + if( !tr.skyboxTextures[i] ) break; + Con_DPrintf( "%s%s, ", skyboxname, r_skyBoxSuffix[i] ); } if( i == 6 ) { SetBits( world.flags, FWORLD_CUSTOM_SKYBOX ); + Con_DPrintf( "done\n" ); return; // loaded } - MsgDev( D_ERROR, "R_SetupSky: couldn't load skybox '%s'\n", skyboxname ); + MsgDev( D_ERROR, "couldn't load skybox '%s'\n", skyboxname ); R_UnloadSkybox(); } diff --git a/engine/client/s_load.c b/engine/client/s_load.c index 1b2e88e6..688b8c47 100644 --- a/engine/client/s_load.c +++ b/engine/client/s_load.c @@ -179,7 +179,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache ) COM_FixSlashes( name ); // see if already loaded - hash = Com_HashKey( name, MAX_SFX_HASH ); + hash = COM_HashKey( name, MAX_SFX_HASH ); for( sfx = s_sfxHashList[hash]; sfx; sfx = sfx->hashNext ) { if( !Q_strcmp( sfx->name, name )) @@ -214,7 +214,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache ) if( pfInCache ) *pfInCache = false; Q_strncpy( sfx->name, name, MAX_STRING ); sfx->touchFrame = s_registration_sequence; - sfx->hashValue = Com_HashKey( sfx->name, MAX_SFX_HASH ); + sfx->hashValue = COM_HashKey( sfx->name, MAX_SFX_HASH ); // link it in sfx->hashNext = s_sfxHashList[sfx->hashValue]; diff --git a/engine/common/avikit.c b/engine/common/avikit.c index 875aa5ee..9fbcadba 100644 --- a/engine/common/avikit.c +++ b/engine/common/avikit.c @@ -625,7 +625,7 @@ movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio ) // open cinematic Q_snprintf( path, sizeof( path ), "media/%s", filename ); - FS_DefaultExtension( path, ".avi" ); + COM_DefaultExtension( path, ".avi" ); fullpath = FS_GetDiskPath( path, false ); if( FS_FileExists( path, false ) && !fullpath ) diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 16bb3656..4687b17d 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -328,8 +328,8 @@ void Cmd_Echo_f( void ) int i; for( i = 1; i < Cmd_Argc(); i++ ) - Sys_Print( Cmd_Argv( i )); - Sys_Print( "\n" ); + Con_Printf( Cmd_Argv( i )); + Con_Printf( "\n" ); } /* diff --git a/engine/common/common.c b/engine/common/common.c index eb147e98..13e46490 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -147,6 +147,163 @@ long COM_RandomLong( long lLow, long lHigh ) return lLow + (n % x); } +/* +============ +COM_FileBase + +Extracts the base name of a file (no path, no extension, assumes '/' as path separator) +============ +*/ +void COM_FileBase( const char *in, char *out ) +{ + int len, start, end; + + len = Q_strlen( in ); + if( !len ) return; + + // scan backward for '.' + end = len - 1; + + while( end && in[end] != '.' && in[end] != '/' && in[end] != '\\' ) + end--; + + if( in[end] != '.' ) + end = len-1; // no '.', copy to end + else end--; // found ',', copy to left of '.' + + // scan backward for '/' + start = len - 1; + + while( start >= 0 && in[start] != '/' && in[start] != '\\' ) + start--; + + if( start < 0 || ( in[start] != '/' && in[start] != '\\' )) + start = 0; + else start++; + + // length of new sting + len = end - start + 1; + + // Copy partial string + Q_strncpy( out, &in[start], len + 1 ); + out[len] = 0; +} + +/* +============ +COM_FileExtension +============ +*/ +const char *COM_FileExtension( const char *in ) +{ + const char *separator, *backslash, *colon, *dot; + + separator = Q_strrchr( in, '/' ); + backslash = Q_strrchr( in, '\\' ); + + if( !separator || separator < backslash ) + separator = backslash; + + colon = Q_strrchr( in, ':' ); + + if( !separator || separator < colon ) + separator = colon; + + dot = Q_strrchr( in, '.' ); + + if( dot == NULL || ( separator && ( dot < separator ))) + return ""; + + return dot + 1; +} + +/* +============ +COM_FileWithoutPath +============ +*/ +const char *COM_FileWithoutPath( const char *in ) +{ + const char *separator, *backslash, *colon; + + separator = Q_strrchr( in, '/' ); + backslash = Q_strrchr( in, '\\' ); + + if( !separator || separator < backslash ) + separator = backslash; + + colon = Q_strrchr( in, ':' ); + + if( !separator || separator < colon ) + separator = colon; + + return separator ? separator + 1 : in; +} + +/* +============ +COM_ExtractFilePath +============ +*/ +void COM_ExtractFilePath( const char *path, char *dest ) +{ + const char *src = path + Q_strlen( path ) - 1; + + // back up until a \ or the start + while( src != path && !(*(src - 1) == '\\' || *(src - 1) == '/' )) + src--; + + if( src != path ) + { + memcpy( dest, path, src - path ); + dest[src - path - 1] = 0; // cutoff backslash + } + else Q_strcpy( dest, "" ); // file without path +} + +/* +============ +COM_StripExtension +============ +*/ +void COM_StripExtension( char *path ) +{ + size_t length; + + length = Q_strlen( path ) - 1; + while( length > 0 && path[length] != '.' ) + { + length--; + if( path[length] == '/' || path[length] == '\\' || path[length] == ':' ) + return; // no extension + } + + if( length ) path[length] = 0; +} + +/* +================== +COM_DefaultExtension +================== +*/ +void COM_DefaultExtension( char *path, const char *extension ) +{ + const char *src; + + // if path doesn't have a .EXT, append extension + // (extension should include the .) + src = path + Q_strlen( path ) - 1; + + while( *src != '/' && src != path ) + { + // it has an extension + if( *src == '.' ) return; + src--; + } + + Q_strcat( path, extension ); +} + /* ============== COM_IsSingleChar @@ -762,54 +919,6 @@ void pfnCVarDirectSet( cvar_t *var, const char *szValue ) Cvar_DirectSet( (convar_t *)var, szValue ); } -/* -============= -Con_Printf - -============= -*/ -void Con_Printf( char *szFmt, ... ) -{ - static char buffer[16384]; // must support > 1k messages - va_list args; - - if( host.developer < D_INFO ) - return; - - va_start( args, szFmt ); - Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args ); - va_end( args ); - - if( buffer[0] == '0' && buffer[1] == '\n' && buffer[2] == '\0' ) - return; // hlrally spam - - Sys_Print( buffer ); -} - -/* -============= -Con_DPrintf - -============= -*/ -void Con_DPrintf( char *szFmt, ... ) -{ - static char buffer[16384]; // must support > 1k messages - va_list args; - - if( host.developer < D_ERROR ) - return; - - va_start( args, szFmt ); - Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args ); - va_end( args ); - - if( buffer[0] == '0' && buffer[1] == '\n' && buffer[2] == '\0' ) - return; // hlrally spam - - Sys_Print( buffer ); -} - /* ============= COM_CompareFileTime @@ -913,7 +1022,7 @@ qboolean COM_IsSafeFileToDownload( const char *filename ) if( Q_strlen( first ) != 4 ) return false; - ext = FS_FileExtension( lwrfilename ); + ext = COM_FileExtension( lwrfilename ); for( i = 0; i < ARRAYSIZE( file_exts ); i++ ) { diff --git a/engine/common/common.h b/engine/common/common.h index 869a119d..44790937 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -402,12 +402,12 @@ void FS_AllowDirectPaths( qboolean enable ); void FS_AddGameDirectory( const char *dir, int flags ); void FS_AddGameHierarchy( const char *dir, int flags ); void FS_LoadGameInfo( const char *rootfolder ); -void FS_FileBase( const char *in, char *out ); -const char *FS_FileExtension( const char *in ); -void FS_DefaultExtension( char *path, const char *extension ); -void FS_ExtractFilePath( const char *path, char *dest ); +void COM_FileBase( const char *in, char *out ); +const char *COM_FileExtension( const char *in ); +void COM_DefaultExtension( char *path, const char *extension ); +void COM_ExtractFilePath( const char *path, char *dest ); const char *FS_GetDiskPath( const char *name, qboolean gamedironly ); -const char *FS_FileWithoutPath( const char *in ); +const char *COM_FileWithoutPath( const char *in ); byte *W_LoadLump( wfile_t *wad, const char *lumpname, size_t *lumpsizeptr, const char type ); void W_Close( wfile_t *wad ); byte *FS_LoadFile( const char *path, long *filesizeptr, qboolean gamedironly ); @@ -435,7 +435,7 @@ qboolean FS_FileExists( const char *filename, qboolean gamedironly ); qboolean FS_FileCopy( file_t *pOutput, file_t *pInput, int fileSize ); qboolean FS_Delete( const char *path ); int FS_UnGetc( file_t *file, byte c ); -void FS_StripExtension( char *path ); +void COM_StripExtension( char *path ); long FS_Tell( file_t *file ); qboolean FS_Eof( file_t *file ); int FS_Close( file_t *file ); @@ -662,8 +662,6 @@ int Q_buildnum( void ); // host.c // void EXPORT Host_Shutdown( void ); -void Host_SetServerState( int state ); -int Host_ServerState( void ); int Host_CompareFileTime( long ft1, long ft2 ); void Host_NewInstance( const char *name, const char *finalmsg ); void Host_EndGame( qboolean abort, const char *message, ... ); @@ -708,7 +706,7 @@ void Host_ClientFrame( void ); qboolean CL_Active( void ); void SV_Init( void ); -void SV_Shutdown( qboolean reconnect ); +void SV_Shutdown( const char *finalmsg ); void Host_ServerFrame( void ); qboolean SV_Active( void ); @@ -773,7 +771,7 @@ void MD5Init( MD5Context_t *ctx ); void MD5Update( MD5Context_t *ctx, const byte *buf, uint len ); void MD5Final( byte digest[16], MD5Context_t *ctx ); qboolean MD5_HashFile( byte digest[16], const char *pszFileName, uint seed[4] ); -uint Com_HashKey( const char *string, uint hashSize ); +uint COM_HashKey( const char *string, uint hashSize ); char *MD5_Print( byte hash[16] ); // diff --git a/engine/common/con_utils.c b/engine/common/con_utils.c index b0d39ef7..07af9acf 100644 --- a/engine/common/con_utils.c +++ b/engine/common/con_utils.c @@ -51,7 +51,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps->value ); if( !t ) return false; - FS_FileBase( t->filenames[0], matchbuf ); + COM_FileBase( t->filenames[0], matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); if( t->numfilenames == 1 ) return true; @@ -59,7 +59,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) for( i = 0, nummaps = 0; i < t->numfilenames; i++ ) { char entfilename[MAX_QPATH]; - const char *ext = FS_FileExtension( t->filenames[i] ); + const char *ext = COM_FileExtension( t->filenames[i] ); int ver = -1, lumpofs = 0, lumplen = 0; char *ents = NULL, *pfile; qboolean validmap = false; @@ -91,8 +91,8 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) if( hdrext->id == IDEXTRAHEADER ) version = hdrext->version; Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename )); - FS_StripExtension( entfilename ); - FS_DefaultExtension( entfilename, ".ent" ); + COM_StripExtension( entfilename ); + COM_DefaultExtension( entfilename, ".ent" ); ents = FS_LoadFile( entfilename, NULL, true ); if( !ents && lumplen >= 10 ) @@ -126,7 +126,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length ) } if( f ) FS_Close(f); - FS_FileBase( t->filenames[i], matchbuf ); + COM_FileBase( t->filenames[i], matchbuf ); switch( ver ) { @@ -180,17 +180,17 @@ qboolean Cmd_GetDemoList( const char *s, char *completedname, int length ) t = FS_Search( va( "demos/%s*.dem", s ), true, true ); // lookup only in gamedir if( !t ) return false; - FS_FileBase( t->filenames[0], matchbuf ); + COM_FileBase( t->filenames[0], matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); if( t->numfilenames == 1 ) return true; for( i = 0, numdems = 0; i < t->numfilenames; i++ ) { - if( Q_stricmp( FS_FileExtension( t->filenames[i] ), "dem" )) + if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "dem" )) continue; - FS_FileBase( t->filenames[i], matchbuf ); + COM_FileBase( t->filenames[i], matchbuf ); Msg( "%16s\n", matchbuf ); numdems++; } @@ -226,17 +226,17 @@ qboolean Cmd_GetMovieList( const char *s, char *completedname, int length ) t = FS_Search( va( "media/%s*.avi", s ), true, false ); if( !t ) return false; - FS_FileBase( t->filenames[0], matchbuf ); + COM_FileBase( t->filenames[0], matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); if( t->numfilenames == 1 ) return true; for(i = 0, nummovies = 0; i < t->numfilenames; i++) { - if( Q_stricmp( FS_FileExtension( t->filenames[i] ), "avi" )) + if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "avi" )) continue; - FS_FileBase( t->filenames[i], matchbuf ); + COM_FileBase( t->filenames[i], matchbuf ); Msg( "%16s\n", matchbuf ); nummovies++; } @@ -273,19 +273,19 @@ qboolean Cmd_GetMusicList( const char *s, char *completedname, int length ) t = FS_Search( va( "media/%s*.*", s ), true, false ); if( !t ) return false; - FS_FileBase( t->filenames[0], matchbuf ); + COM_FileBase( t->filenames[0], matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); if( t->numfilenames == 1 ) return true; for(i = 0, numtracks = 0; i < t->numfilenames; i++) { - const char *ext = FS_FileExtension( t->filenames[i] ); + const char *ext = COM_FileExtension( t->filenames[i] ); if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" )) continue; - FS_FileBase( t->filenames[i], matchbuf ); + COM_FileBase( t->filenames[i], matchbuf ); Msg( "%16s\n", matchbuf ); numtracks++; } @@ -321,17 +321,17 @@ qboolean Cmd_GetSavesList( const char *s, char *completedname, int length ) t = FS_Search( va( "save/%s*.sav", s ), true, true ); // lookup only in gamedir if( !t ) return false; - FS_FileBase( t->filenames[0], matchbuf ); + COM_FileBase( t->filenames[0], matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); if( t->numfilenames == 1 ) return true; for( i = 0, numsaves = 0; i < t->numfilenames; i++ ) { - if( Q_stricmp( FS_FileExtension( t->filenames[i] ), "sav" )) + if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "sav" )) continue; - FS_FileBase( t->filenames[i], matchbuf ); + COM_FileBase( t->filenames[i], matchbuf ); Msg( "%16s\n", matchbuf ); numsaves++; } @@ -368,17 +368,17 @@ qboolean Cmd_GetConfigList( const char *s, char *completedname, int length ) t = FS_Search( va( "%s*.cfg", s ), true, false ); if( !t ) return false; - FS_FileBase( t->filenames[0], matchbuf ); + COM_FileBase( t->filenames[0], matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); if( t->numfilenames == 1 ) return true; for( i = 0, numconfigs = 0; i < t->numfilenames; i++ ) { - if( Q_stricmp( FS_FileExtension( t->filenames[i] ), "cfg" )) + if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "cfg" )) continue; - FS_FileBase( t->filenames[i], matchbuf ); + COM_FileBase( t->filenames[i], matchbuf ); Msg( "%16s\n", matchbuf ); numconfigs++; } @@ -417,20 +417,20 @@ qboolean Cmd_GetSoundList( const char *s, char *completedname, int length ) if( !t ) return false; Q_strncpy( matchbuf, t->filenames[0] + Q_strlen( snddir ), MAX_STRING ); - FS_StripExtension( matchbuf ); + COM_StripExtension( matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); if( t->numfilenames == 1 ) return true; for(i = 0, numsounds = 0; i < t->numfilenames; i++) { - const char *ext = FS_FileExtension( t->filenames[i] ); + const char *ext = COM_FileExtension( t->filenames[i] ); if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" )) continue; Q_strncpy( matchbuf, t->filenames[i] + Q_strlen(snddir), MAX_STRING ); - FS_StripExtension( matchbuf ); + COM_StripExtension( matchbuf ); Msg( "%16s\n", matchbuf ); numsounds++; } @@ -468,17 +468,17 @@ qboolean Cmd_GetItemsList( const char *s, char *completedname, int length ) t = FS_Search( va( "%s/%s*.txt", clgame.itemspath, s ), true, false ); if( !t ) return false; - FS_FileBase( t->filenames[0], matchbuf ); + COM_FileBase( t->filenames[0], matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); if( t->numfilenames == 1 ) return true; for(i = 0, numitems = 0; i < t->numfilenames; i++) { - if( Q_stricmp( FS_FileExtension( t->filenames[i] ), "txt" )) + if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "txt" )) continue; - FS_FileBase( t->filenames[i], matchbuf ); + COM_FileBase( t->filenames[i], matchbuf ); Msg( "%16s\n", matchbuf ); numitems++; } @@ -514,17 +514,17 @@ qboolean Cmd_GetCustomList( const char *s, char *completedname, int length ) t = FS_Search( va( "%s*.hpk", s ), true, false ); if( !t ) return false; - FS_FileBase( t->filenames[0], matchbuf ); + COM_FileBase( t->filenames[0], matchbuf ); if( completedname && length ) Q_strncpy( completedname, matchbuf, length ); if( t->numfilenames == 1 ) return true; for(i = 0, numitems = 0; i < t->numfilenames; i++) { - if( Q_stricmp( FS_FileExtension( t->filenames[i] ), "hpk" )) + if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "hpk" )) continue; - FS_FileBase( t->filenames[i], matchbuf ); + COM_FileBase( t->filenames[i], matchbuf ); Msg( "%16s\n", matchbuf ); numitems++; } @@ -687,11 +687,11 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) int lumpofs = 0, lumplen = 0; string mapname, message, entfilename; - if( Q_stricmp( FS_FileExtension( t->filenames[i] ), "bsp" )) + if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "bsp" )) continue; f = FS_Open( t->filenames[i], "rb", onlyingamedir ); - FS_FileBase( t->filenames[i], mapname ); + COM_FileBase( t->filenames[i], mapname ); if( f ) { @@ -714,8 +714,8 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) lumplen = header->lumps[LUMP_ENTITIES].filelen; Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename )); - FS_StripExtension( entfilename ); - FS_DefaultExtension( entfilename, ".ent" ); + COM_StripExtension( entfilename ); + COM_DefaultExtension( entfilename, ".ent" ); ents = FS_LoadFile( entfilename, NULL, true ); if( !ents && lumplen >= 10 ) diff --git a/engine/common/console.c b/engine/common/console.c index 76904982..7a716613 100644 --- a/engine/common/console.c +++ b/engine/common/console.c @@ -434,7 +434,8 @@ void Con_AddLine( const char *line, int length ) byte *putpos; con_lineinfo_t *p; - if( !con.initialized ) return; + if( !con.initialized || !con.buffer ) + return; Con_FixTimes(); length++; // reserve space for term @@ -1011,7 +1012,7 @@ void Con_Print( const char *txt ) int c, mask; // client not running - if( !con.initialized || !con.buffer || host.type == HOST_DEDICATED ) + if( !con.initialized || !con.buffer ) return; if( txt[0] == 2 ) @@ -1056,6 +1057,54 @@ void Con_Print( const char *txt ) } } +/* +============= +Con_Printf + +============= +*/ +void Con_Printf( char *szFmt, ... ) +{ + static char buffer[MAX_PRINT_MSG]; + va_list args; + + if( host.developer <= 0 ) + return; + + va_start( args, szFmt ); + Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args ); + va_end( args ); + + if( buffer[0] == '0' && buffer[1] == '\n' && buffer[2] == '\0' ) + return; // hlrally spam + + Sys_Print( buffer ); +} + +/* +============= +Con_DPrintf + +============= +*/ +void Con_DPrintf( char *szFmt, ... ) +{ + static char buffer[MAX_PRINT_MSG]; + va_list args; + + if( host.developer < D_ERROR ) + return; + + va_start( args, szFmt ); + Q_vsnprintf( buffer, sizeof( buffer ), szFmt, args ); + va_end( args ); + + if( buffer[0] == '0' && buffer[1] == '\n' && buffer[2] == '\0' ) + return; // hlrally spam + + Sys_Print( buffer ); +} + /* ================ Con_NPrint @@ -1914,6 +1963,9 @@ int Con_DrawConsoleLine( int y, int lineno ) { con_lineinfo_t *li = &CON_LINES( lineno ); + if( *li->start == '\1' ) + return 0; // this string will be shown only at notify + if( y >= con.curFont->charHeight ) Con_DrawGenericString( con.curFont->charWidths[' '], y, li->start, g_color_table[7], false, -1 ); diff --git a/engine/common/crclib.c b/engine/common/crclib.c index 8df1d4fe..b1eece7e 100644 --- a/engine/common/crclib.c +++ b/engine/common/crclib.c @@ -203,9 +203,9 @@ byte CRC32_BlockSequence( byte *base, int length, int sequence ) qboolean CRC32_File( dword *crcvalue, const char *filename ) { - file_t *f; char buffer[1024]; int num_bytes; + file_t *f; f = FS_Open( filename, "rb", false ); if( !f ) return false; @@ -588,12 +588,12 @@ char *MD5_Print( byte hash[16] ) /* ================= -Com_HashKey +COM_HashKey returns hash key for string ================= */ -uint Com_HashKey( const char *string, uint hashSize ) +uint COM_HashKey( const char *string, uint hashSize ) { uint i, hashKey = 0; diff --git a/engine/common/filesystem.c b/engine/common/filesystem.c index 5c989d79..797c48d2 100644 --- a/engine/common/filesystem.c +++ b/engine/common/filesystem.c @@ -112,7 +112,6 @@ qboolean fs_ext_path = false; // attempt to read\write from ./ or ../ pathes static const wadtype_t wad_hints[10]; static void FS_InitMemory( void ); -const char *FS_FileExtension( const char *in ); static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedironly ); static dlumpinfo_t *W_FindLump( wfile_t *wad, const char *name, const char matchtype ); static dpackfile_t *FS_AddFileToPack( const char* name, pack_t *pack, long offset, long size ); @@ -393,48 +392,6 @@ void FS_ClearPaths_f( void ) FS_ClearSearchPath(); } -/* -============ -FS_FileBase - -Extracts the base name of a file (no path, no extension, assumes '/' as path separator) -============ -*/ -void FS_FileBase( const char *in, char *out ) -{ - int len, start, end; - - len = Q_strlen( in ); - if( !len ) return; - - // scan backward for '.' - end = len - 1; - - while( end && in[end] != '.' && in[end] != '/' && in[end] != '\\' ) - end--; - - if( in[end] != '.' ) - end = len-1; // no '.', copy to end - else end--; // found ',', copy to left of '.' - - // scan backward for '/' - start = len - 1; - - while( start >= 0 && in[start] != '/' && in[start] != '\\' ) - start--; - - if( start < 0 || ( in[start] != '/' && in[start] != '\\' )) - start = 0; - else start++; - - // length of new sting - len = end - start + 1; - - // Copy partial string - Q_strncpy( out, &in[start], len + 1 ); - out[len] = 0; -} - /* ================= FS_LoadPackPAK @@ -536,7 +493,7 @@ static qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loade { searchpath_t *search; wfile_t *wad = NULL; - const char *ext = FS_FileExtension( wadfile ); + const char *ext = COM_FileExtension( wadfile ); int errorcode = WAD_LOAD_COULDNT_OPEN; for( search = fs_searchpaths; search; search = search->next ) @@ -589,7 +546,7 @@ static qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loade { searchpath_t *search; pack_t *pak = NULL; - const char *ext = FS_FileExtension( pakfile ); + const char *ext = COM_FileExtension( pakfile ); int i, errorcode = PAK_LOAD_COULDNT_OPEN; for( search = fs_searchpaths; search; search = search->next ) @@ -621,7 +578,7 @@ static qboolean FS_AddPak_Fullpath( const char *pakfile, qboolean *already_loade // time to add in search list all the wads that contains in current pakfile (if do) for( i = 0; i < pak->numfiles; i++ ) { - if( !Q_stricmp( FS_FileExtension( pak->files[i].name ), "wad" )) + if( !Q_stricmp( COM_FileExtension( pak->files[i].name ), "wad" )) { Q_sprintf( fullpath, "%s/%s", pakfile, pak->files[i].name ); FS_AddWad_Fullpath( fullpath, NULL, flags ); @@ -663,7 +620,7 @@ void FS_AddGameDirectory( const char *dir, int flags ) // add any PAK package in the directory for( i = 0; i < list.numstrings; i++ ) { - if( !Q_stricmp( FS_FileExtension( list.strings[i] ), "pak" )) + if( !Q_stricmp( COM_FileExtension( list.strings[i] ), "pak" )) { Q_sprintf( fullpath, "%s%s", dir, list.strings[i] ); FS_AddPak_Fullpath( fullpath, NULL, flags ); @@ -675,7 +632,7 @@ void FS_AddGameDirectory( const char *dir, int flags ) // add any WAD package in the directory for( i = 0; i < list.numstrings; i++ ) { - if( !Q_stricmp( FS_FileExtension( list.strings[i] ), "wad" )) + if( !Q_stricmp( COM_FileExtension( list.strings[i] ), "wad" )) { Q_sprintf( fullpath, "%s%s", dir, list.strings[i] ); FS_AddWad_Fullpath( fullpath, NULL, flags ); @@ -702,79 +659,8 @@ FS_AddGameHierarchy void FS_AddGameHierarchy( const char *dir, int flags ) { // Add the common game directory - if( dir && *dir ) FS_AddGameDirectory( va( "%s/", dir ), flags ); -} - -/* -============ -FS_FileExtension -============ -*/ -const char *FS_FileExtension( const char *in ) -{ - const char *separator, *backslash, *colon, *dot; - - separator = Q_strrchr( in, '/' ); - backslash = Q_strrchr( in, '\\' ); - - if( !separator || separator < backslash ) - separator = backslash; - - colon = Q_strrchr( in, ':' ); - - if( !separator || separator < colon ) - separator = colon; - - dot = Q_strrchr( in, '.' ); - - if( dot == NULL || ( separator && ( dot < separator ))) - return ""; - - return dot + 1; -} - -/* -============ -FS_FileWithoutPath -============ -*/ -const char *FS_FileWithoutPath( const char *in ) -{ - const char *separator, *backslash, *colon; - - separator = Q_strrchr( in, '/' ); - backslash = Q_strrchr( in, '\\' ); - - if( !separator || separator < backslash ) - separator = backslash; - - colon = Q_strrchr( in, ':' ); - - if( !separator || separator < colon ) - separator = colon; - - return separator ? separator + 1 : in; -} - -/* -============ -FS_ExtractFilePath -============ -*/ -void FS_ExtractFilePath( const char *path, char *dest ) -{ - const char *src = path + Q_strlen( path ) - 1; - - // back up until a \ or the start - while( src != path && !(*(src - 1) == '\\' || *(src - 1) == '/' )) - src--; - - if( src != path ) - { - memcpy( dest, path, src - path ); - dest[src - path - 1] = 0; // cutoff backslash - } - else Q_strcpy( dest, "" ); // file without path + if( COM_CheckString( dir )) + FS_AddGameDirectory( va( "%s/", dir ), flags ); } /* @@ -828,7 +714,7 @@ Return true if the path should be rejected due to one of the following: int FS_CheckNastyPath( const char *path, qboolean isgamedir ) { // all: never allow an empty path, as for gamedir it would access the parent directory and a non-gamedir path it is just useless - if( !path[0] ) return 2; + if( !COM_CheckString( path )) return 2; // Mac: don't allow Mac-only filenames - : is a directory separator // instead of /, but we rely on / working already, so there's no reason to @@ -1060,12 +946,12 @@ static qboolean FS_ParseLiblistGam( const char *filename, const char *gamedir, g else if( !Q_stricmp( token, "startmap" )) { pfile = COM_ParseFile( pfile, GameInfo->startmap ); - FS_StripExtension( GameInfo->startmap ); // HQ2:Amen has extension .bsp + COM_StripExtension( GameInfo->startmap ); // HQ2:Amen has extension .bsp } else if( !Q_stricmp( token, "trainmap" ) || !Q_stricmp( token, "trainingmap" )) { pfile = COM_ParseFile( pfile, GameInfo->trainmap ); - FS_StripExtension( GameInfo->trainmap ); // HQ2:Amen has extension .bsp + COM_StripExtension( GameInfo->trainmap ); // HQ2:Amen has extension .bsp } else if( !Q_stricmp( token, "url_info" )) { @@ -1084,7 +970,7 @@ static qboolean FS_ParseLiblistGam( const char *filename, const char *gamedir, g { pfile = COM_ParseFile( pfile, GameInfo->iconpath ); COM_FixSlashes( GameInfo->iconpath ); - FS_DefaultExtension( GameInfo->iconpath, ".ico" ); + COM_DefaultExtension( GameInfo->iconpath, ".ico" ); } else if( !Q_stricmp( token, "type" )) { @@ -1162,6 +1048,11 @@ void FS_ConvertGameInfo( const char *gamedir, const char *gameinfo_path, const c } } +/* +================ +FS_ReadGameInfo +================ +*/ static qboolean FS_ReadGameInfo( const char *filepath, const char *gamedir, gameinfo_t *GameInfo ) { char *afile, *pfile; @@ -1233,17 +1124,17 @@ static qboolean FS_ReadGameInfo( const char *filepath, const char *gamedir, game else if( !Q_stricmp( token, "startmap" )) { pfile = COM_ParseFile( pfile, GameInfo->startmap ); - FS_StripExtension( GameInfo->startmap ); // HQ2:Amen has extension .bsp + COM_StripExtension( GameInfo->startmap ); // HQ2:Amen has extension .bsp } else if( !Q_stricmp( token, "trainmap" )) { pfile = COM_ParseFile( pfile, GameInfo->trainmap ); - FS_StripExtension( GameInfo->trainmap ); // HQ2:Amen has extension .bsp + COM_StripExtension( GameInfo->trainmap ); // HQ2:Amen has extension .bsp } else if( !Q_stricmp( token, "icon" )) { pfile = COM_ParseFile( pfile, GameInfo->iconpath ); - FS_DefaultExtension( GameInfo->iconpath, ".ico" ); + COM_DefaultExtension( GameInfo->iconpath, ".ico" ); } else if( !Q_stricmp( token, "url_info" )) { @@ -1762,20 +1653,20 @@ static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedir // quick reject by filetype if( type == TYP_NONE ) continue; - FS_ExtractFilePath( name, wadname ); + COM_ExtractFilePath( name, wadname ); wadfolder[0] = '\0'; if( Q_strlen( wadname )) { - FS_FileBase( wadname, wadname ); + COM_FileBase( wadname, wadname ); Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); - FS_DefaultExtension( wadname, ".wad" ); + COM_DefaultExtension( wadname, ".wad" ); anywadname = false; } // make wadname from wad fullpath - FS_FileBase( search->wad->filename, shortname ); - FS_DefaultExtension( shortname, ".wad" ); + COM_FileBase( search->wad->filename, shortname ); + COM_DefaultExtension( shortname, ".wad" ); // quick reject by wadname if( !anywadname && Q_stricmp( wadname, shortname )) @@ -1783,7 +1674,7 @@ static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedir // NOTE: we can't using long names for wad, // because we using original wad names[16]; - FS_FileBase( name, shortname ); + COM_FileBase( name, shortname ); lump = W_FindLump( search->wad, shortname, type ); @@ -2346,49 +2237,6 @@ OTHERS PUBLIC FUNCTIONS ============================================================================= */ -/* -============ -FS_StripExtension -============ -*/ -void FS_StripExtension( char *path ) -{ - size_t length; - - length = Q_strlen( path ) - 1; - while( length > 0 && path[length] != '.' ) - { - length--; - if( path[length] == '/' || path[length] == '\\' || path[length] == ':' ) - return; // no extension - } - - if( length ) path[length] = 0; -} - -/* -================== -FS_DefaultExtension -================== -*/ -void FS_DefaultExtension( char *path, const char *extension ) -{ - const char *src; - - // if path doesn't have a .EXT, append extension - // (extension should include the .) - src = path + Q_strlen( path ) - 1; - - while( *src != '/' && src != path ) - { - // it has an extension - if( *src == '.' ) return; - src--; - } - - Q_strcat( path, extension ); -} - /* ================== FS_FileExists @@ -2484,7 +2332,7 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath ) } dllpath[i] = '\0'; - FS_DefaultExtension( dllpath, ".dll" ); // apply ext if forget + COM_DefaultExtension( dllpath, ".dll" ); // apply ext if forget search = FS_FindFile( dllpath, &index, false ); if( !search ) @@ -2769,21 +2617,21 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ) // quick reject by filetype if( type == TYP_NONE ) continue; - FS_ExtractFilePath( pattern, wadname ); - FS_FileBase( pattern, wadpattern ); + COM_ExtractFilePath( pattern, wadname ); + COM_FileBase( pattern, wadpattern ); wadfolder[0] = '\0'; if( Q_strlen( wadname )) { - FS_FileBase( wadname, wadname ); + COM_FileBase( wadname, wadname ); Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); - FS_DefaultExtension( wadname, ".wad" ); + COM_DefaultExtension( wadname, ".wad" ); anywadname = false; } // make wadname from wad fullpath - FS_FileBase( searchpath->wad->filename, temp2 ); - FS_DefaultExtension( temp2, ".wad" ); + COM_FileBase( searchpath->wad->filename, temp2 ); + COM_DefaultExtension( temp2, ".wad" ); // quick reject by wadname if( !anywadname && Q_stricmp( wadname, temp2 )) @@ -2815,7 +2663,7 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly ) { // build path: wadname/lumpname.ext Q_snprintf( temp2, sizeof(temp2), "%s/%s", wadfolder, temp ); - FS_DefaultExtension( temp2, va(".%s", W_ExtFromType( wad->lumps[i].type ))); + COM_DefaultExtension( temp2, va(".%s", W_ExtFromType( wad->lumps[i].type ))); stringlistappend( &resultlist, temp2 ); } } @@ -2946,7 +2794,7 @@ Extracts file type from extension */ static char W_TypeFromExt( const char *lumpname ) { - const char *ext = FS_FileExtension( lumpname ); + const char *ext = COM_FileExtension( lumpname ); const wadtype_t *type; // we not known about filetype, so match only by filename @@ -2999,7 +2847,7 @@ char W_HintFromSuf( const char *lumpname ) const wadtype_t *hint; // trying to extract hint from the name - FS_FileBase( lumpname, barename ); + COM_FileBase( lumpname, barename ); namelen = Q_strlen( barename ); if( namelen <= HINT_NAMELEN ) @@ -3037,7 +2885,7 @@ static dlumpinfo_t *W_FindLump( wfile_t *wad, const char *name, const char match return NULL; // trying to extract hint from the name - FS_FileBase( name, barename ); + COM_FileBase( name, barename ); namelen = Q_strlen( barename ); if( namelen > HINT_NAMELEN ) @@ -3209,7 +3057,7 @@ wfile_t *W_Open( const char *filename, int *error ) // NOTE: FS_Open is load wad file from the first pak in the list (while fs_ext_path is false) if( fs_ext_path ) wad->handle = FS_Open( filename, "rb", false ); - else wad->handle = FS_Open( FS_FileWithoutPath( filename ), "rb", false ); + else wad->handle = FS_Open( COM_FileWithoutPath( filename ), "rb", false ); if( wad->handle == NULL ) { diff --git a/engine/common/host.c b/engine/common/host.c index 104d8bd0..3e89f70b 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -29,7 +29,6 @@ HINSTANCE hCurrent; // hinstance of current .dll host_parm_t host; // host parms sysinfo_t SI; -convar_t *host_serverstate; convar_t *host_gameloaded; convar_t *host_clientloaded; convar_t *host_limitlocal; @@ -38,12 +37,6 @@ convar_t *host_framerate; convar_t *con_gamemaps; convar_t *build, *ver; -// these cvars will be duplicated on each client across network -int Host_ServerState( void ) -{ - return Cvar_VariableInteger( "host_serverstate" ); -} - int Host_CompareFileTime( long ft1, long ft2 ) { if( ft1 < ft2 ) @@ -59,9 +52,7 @@ int Host_CompareFileTime( long ft1, long ft2 ) void Host_ShutdownServer( void ) { - if( !SV_Initialized( )) return; - Q_strncpy( host.finalmsg, "Server was killed", MAX_STRING ); - SV_Shutdown( false ); + SV_Shutdown( "Server was killed\n" ); } /* @@ -105,13 +96,8 @@ void Host_EndGame( qboolean abort, const char *message, ... ) va_end( argptr ); MsgDev( D_INFO, "Host_EndGame: %s\n", string ); - - if( SV_Initialized( )) - { - Q_snprintf( host.finalmsg, sizeof( host.finalmsg ), "Host_EndGame: %s", string ); - SV_Shutdown( false ); - } + SV_Shutdown( "\n" ); CL_Disconnect(); // recreate world if needs @@ -135,16 +121,6 @@ void Host_AbortCurrentFrame( void ) longjmp( host.abortframe, 1 ); } -/* -================== -Host_SetServerState -================== -*/ -void Host_SetServerState( int state ) -{ - Cvar_FullSet( "host_serverstate", va( "%i", state ), FCVAR_READ_ONLY ); -} - /* ================== Host_CheckSleep @@ -161,7 +137,7 @@ void Host_CheckSleep( void ) { if( host.status == HOST_NOFOCUS ) { - if( Host_ServerState() && CL_IsInGame( )) + if( SV_Active() && CL_IsInGame( )) Sys_Sleep( 1 ); // listenserver else Sys_Sleep( 20 ); // sleep 20 ms otherwise } @@ -248,7 +224,7 @@ void Host_Exec_f( void ) } Q_strncpy( cfgpath, Cmd_Argv( 1 ), sizeof( cfgpath )); - FS_DefaultExtension( cfgpath, ".cfg" ); // append as default + COM_DefaultExtension( cfgpath, ".cfg" ); // append as default f = FS_LoadFile( cfgpath, &len, false ); if( !f ) @@ -340,7 +316,7 @@ qboolean Host_RegisterDecal( const char *name, int *count ) if( !name || !*name ) return 0; - FS_FileBase( name, shortname ); + COM_FileBase( name, shortname ); for( i = 1; i < MAX_DECALS && host.draw_decals[i][0]; i++ ) { @@ -690,7 +666,7 @@ void Host_Error( const char *error, ... ) // clearing cmd buffer to prevent execute any commands Cbuf_Clear(); - SV_Shutdown( false ); + Host_ShutdownServer(); CL_Drop(); // drop clients // recreate world if needs @@ -810,9 +786,9 @@ void Host_InitCommon( const char *hostname, qboolean bChangeGame ) // we can specified custom name, from Sys_NewInstance if( GetModuleFileName( NULL, szTemp, sizeof( szTemp )) && !host.change_game ) - FS_FileBase( szTemp, SI.exeName ); + COM_FileBase( szTemp, SI.exeName ); - FS_ExtractFilePath( szTemp, szRootPath ); + COM_ExtractFilePath( szTemp, szRootPath ); if( Q_stricmp( host.rootdir, szRootPath )) { Q_strncpy( host.rootdir, szRootPath, sizeof( host.rootdir )); @@ -934,7 +910,6 @@ int EXPORT Host_Main( const char *progname, int bChangeGame, pfnChangeGame func host_maxfps = Cvar_Get( "fps_max", "72", FCVAR_ARCHIVE, "host fps upper limit" ); host_framerate = Cvar_Get( "host_framerate", "0", 0, "locks frame timing to this value in seconds" ); - host_serverstate = Cvar_Get( "host_serverstate", "0", FCVAR_READ_ONLY, "displays current server state" ); host_gameloaded = Cvar_Get( "host_gameloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded game.dll" ); host_clientloaded = Cvar_Get( "host_clientloaded", "0", FCVAR_READ_ONLY, "inidcates a loaded client.dll" ); host_limitlocal = Cvar_Get( "host_limitlocal", "0", 0, "apply cl_cmdrate and rate to loopback connection" ); @@ -1030,7 +1005,7 @@ void EXPORT Host_Shutdown( void ) if( host.type == HOST_NORMAL ) Host_WriteConfig(); - SV_Shutdown( false ); + SV_Shutdown( "" ); CL_Shutdown(); Mod_Shutdown(); diff --git a/engine/common/hpak.c b/engine/common/hpak.c index 08ea6e8f..e43b5abb 100644 --- a/engine/common/hpak.c +++ b/engine/common/hpak.c @@ -100,8 +100,8 @@ void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *pData, f } Q_strncpy( pakname, filename, sizeof( pakname )); - FS_StripExtension( pakname ); - FS_DefaultExtension( pakname, ".hpk" ); + COM_StripExtension( pakname ); + COM_DefaultExtension( pakname, ".hpk" ); MsgDev( D_INFO, "creating HPAK %s.\n", pakname ); @@ -249,8 +249,8 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource, } Q_strncpy( srcname, name, sizeof( srcname )); - FS_StripExtension( srcname ); - FS_DefaultExtension( srcname, ".hpk" ); + COM_StripExtension( srcname ); + COM_DefaultExtension( srcname, ".hpk" ); file_src = FS_Open( srcname, "rb", false ); @@ -262,8 +262,8 @@ void HPAK_AddLump( qboolean bUseQueue, const char *name, resource_t *pResource, } Q_strncpy( dstname, srcname, sizeof( dstname )); - FS_StripExtension( dstname ); - FS_DefaultExtension( dstname, ".hp2" ); + COM_StripExtension( dstname ); + COM_DefaultExtension( dstname, ".hp2" ); file_dst = FS_Open( dstname, "w+b", false ); @@ -379,8 +379,8 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet ) return true; Q_strncpy( pakname, filename, sizeof( pakname )); - FS_StripExtension( pakname ); - FS_DefaultExtension( pakname, ".hpk" ); + COM_StripExtension( pakname ); + COM_DefaultExtension( pakname, ".hpk" ); f = FS_Open( pakname, "rb", false ); if( !f ) @@ -480,8 +480,8 @@ void HPAK_CheckIntegrity( const char *filename ) return; Q_strncpy( pakname, filename, sizeof( pakname )); - FS_StripExtension( pakname ); - FS_DefaultExtension( pakname, ".hpk" ); + COM_StripExtension( pakname ); + COM_DefaultExtension( pakname, ".hpk" ); HPAK_ValidatePak( pakname ); } @@ -498,8 +498,8 @@ void HPAK_CheckSize( const char *filename ) return; Q_strncpy( pakname, filename, sizeof( pakname )); - FS_StripExtension( pakname ); - FS_DefaultExtension( pakname, ".hpk" ); + COM_StripExtension( pakname ); + COM_DefaultExtension( pakname, ".hpk" ); if( FS_FileSize( pakname, false ) > ( maxsize * 1000000 )) { @@ -532,8 +532,8 @@ qboolean HPAK_ResourceForHash( const char *filename, byte *hash, resource_t *pRe } Q_strncpy( pakname, filename, sizeof( pakname )); - FS_StripExtension( pakname ); - FS_DefaultExtension( pakname, ".hpk" ); + COM_StripExtension( pakname ); + COM_DefaultExtension( pakname, ".hpk" ); f = FS_Open( pakname, "rb", false ); if( !f ) return false; @@ -581,8 +581,8 @@ static qboolean HPAK_ResourceForIndex( const char *filename, int index, resource return false; Q_strncpy( pakname, filename, sizeof( pakname )); - FS_StripExtension( pakname ); - FS_DefaultExtension( pakname, ".hpk" ); + COM_StripExtension( pakname ); + COM_DefaultExtension( pakname, ".hpk" ); f = FS_Open( pakname, "rb", false ); if( !f ) @@ -668,8 +668,8 @@ qboolean HPAK_GetDataPointer( const char *filename, resource_t *pResource, byte } Q_strncpy( pakname, filename, sizeof( pakname )); - FS_StripExtension( pakname ); - FS_DefaultExtension( pakname, ".hpk" ); + COM_StripExtension( pakname ); + COM_DefaultExtension( pakname, ".hpk" ); f = FS_Open( pakname, "rb", false ); if( !f ) return false; @@ -750,8 +750,8 @@ void HPAK_RemoveLump( const char *name, resource_t *pResource ) HPAK_FlushHostQueue(); Q_strncpy( read_path, name, sizeof( read_path )); - FS_StripExtension( read_path ); - FS_DefaultExtension( read_path, ".hpk" ); + COM_StripExtension( read_path ); + COM_DefaultExtension( read_path, ".hpk" ); file_src = FS_Open( read_path, "rb", false ); if( !file_src ) @@ -761,8 +761,8 @@ void HPAK_RemoveLump( const char *name, resource_t *pResource ) } Q_strncpy( save_path, read_path, sizeof( save_path )); - FS_StripExtension( save_path ); - FS_DefaultExtension( save_path, ".hp2" ); + COM_StripExtension( save_path ); + COM_DefaultExtension( save_path, ".hp2" ); file_dst = FS_Open( save_path, "w+b", false ); if( !file_dst ) @@ -881,8 +881,8 @@ void HPAK_List_f( void ) HPAK_FlushHostQueue(); Q_strncpy( pakname, Cmd_Argv( 1 ), sizeof( pakname )); - FS_StripExtension( pakname ); - FS_DefaultExtension( pakname, ".hpk" ); + COM_StripExtension( pakname ); + COM_DefaultExtension( pakname, ".hpk" ); Msg( "Contents for %s.\n", pakname ); f = FS_Open( pakname, "rb", false ); @@ -927,7 +927,7 @@ void HPAK_List_f( void ) for( nCurrent = 0; nCurrent < directory.count; nCurrent++ ) { entry = &directory.entries[nCurrent]; - FS_FileBase( entry->resource.szFileName, lumpname ); + COM_FileBase( entry->resource.szFileName, lumpname ); type = HPAK_TypeFromIndex( entry->resource.type ); size = Q_memprint( entry->resource.nDownloadSize ); @@ -973,8 +973,8 @@ void HPAK_Extract_f( void ) HPAK_FlushHostQueue(); Q_strncpy( pakname, Cmd_Argv( 1 ), sizeof( pakname )); - FS_StripExtension( pakname ); - FS_DefaultExtension( pakname, ".hpk" ); + COM_StripExtension( pakname ); + COM_DefaultExtension( pakname, ".hpk" ); Msg( "Contents for %s.\n", pakname ); f = FS_Open( pakname, "rb", false ); @@ -1023,7 +1023,7 @@ void HPAK_Extract_f( void ) if( nIndex != -1 && nIndex != nCurrent ) continue; - FS_FileBase( entry->resource.szFileName, lumpname ); + COM_FileBase( entry->resource.szFileName, lumpname ); type = HPAK_TypeFromIndex( entry->resource.type ); size = Q_memprint( entry->resource.nDownloadSize ); diff --git a/engine/common/imagelib/img_main.c b/engine/common/imagelib/img_main.c index 33b50dff..23fee969 100644 --- a/engine/common/imagelib/img_main.c +++ b/engine/common/imagelib/img_main.c @@ -221,7 +221,7 @@ loading and unpack to rgba any known image */ rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size ) { - const char *ext = FS_FileExtension( filename ); + const char *ext = COM_FileExtension( filename ); string path, loadname, sidename; qboolean anyformat = true; int i, filesize = 0; @@ -240,7 +240,7 @@ rgbdata_t *FS_LoadImage( const char *filename, const byte *buffer, size_t size ) { if( !Q_stricmp( format->ext, ext )) { - FS_StripExtension( loadname ); + COM_StripExtension( loadname ); anyformat = false; break; } @@ -364,7 +364,7 @@ writes image as any known format */ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix ) { - const char *ext = FS_FileExtension( filename ); + const char *ext = COM_FileExtension( filename ); qboolean anyformat = !Q_stricmp( ext, "" ) ? true : false; string path, savename; const savepixformat_t *format; @@ -377,7 +377,7 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix ) } Q_strncpy( savename, filename, sizeof( savename )); - FS_StripExtension( savename ); // remove extension if needed + COM_StripExtension( savename ); // remove extension if needed if( pix->flags & (IMAGE_CUBEMAP|IMAGE_SKYBOX)) { diff --git a/engine/common/library.c b/engine/common/library.c index 0065e1ae..8b76c78e 100644 --- a/engine/common/library.c +++ b/engine/common/library.c @@ -268,7 +268,7 @@ static int BuildImportTable( MEMORYMODULE *module ) void *handle; libname = (LPCSTR)CALCULATE_ADDRESS( codeBase, importDesc->Name ); - handle = Com_LoadLibraryExt( libname, false, true ); + handle = COM_LoadLibraryExt( libname, false, true ); if( handle == NULL ) { @@ -297,13 +297,13 @@ static int BuildImportTable( MEMORYMODULE *module ) if( IMAGE_SNAP_BY_ORDINAL( *thunkRef )) { LPCSTR funcName = (LPCSTR)IMAGE_ORDINAL( *thunkRef ); - *funcRef = (DWORD)Com_GetProcAddress( handle, funcName ); + *funcRef = (DWORD)COM_GetProcAddress( handle, funcName ); } else { PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)CALCULATE_ADDRESS( codeBase, *thunkRef ); LPCSTR funcName = (LPCSTR)&thunkData->Name; - *funcRef = (DWORD)Com_GetProcAddress( handle, funcName ); + *funcRef = (DWORD)COM_GetProcAddress( handle, funcName ); } if( *funcRef == 0 ) @@ -340,9 +340,7 @@ static void MemoryFreeLibrary( void *hInstance ) for( i = 0; i < module->numModules; i++ ) { if( module->modules[i] != NULL ) - { - Com_FreeLibrary( module->modules[i] ); - } + COM_FreeLibrary( module->modules[i] ); } Mem_Free( module->modules ); // Mem_Realloc end } @@ -742,7 +740,7 @@ qboolean LibraryLoadSymbols( dll_user_t *hInst ) void *fn_offset; index = hInst->ordinals[i]; - fn_offset = (void *)Com_GetProcAddress( hInst, "GiveFnptrsToDll" ); + fn_offset = (void *)COM_GetProcAddress( hInst, "GiveFnptrsToDll" ); hInst->funcBase = (dword)(fn_offset) - hInst->funcs[index]; break; } @@ -762,12 +760,12 @@ table_error: /* ================ -Com_LoadLibrary +COM_LoadLibrary smart dll loader - can loading dlls from pack or wad files ================ */ -void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolean directpath ) +void *COM_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolean directpath ) { dll_user_t *hInst; @@ -789,7 +787,7 @@ void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolea if( !hInst->hInstance ) { MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s - failed\n", dllname ); - Com_FreeLibrary( hInst ); + COM_FreeLibrary( hInst ); return NULL; } @@ -799,7 +797,7 @@ void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolea if( !LibraryLoadSymbols( hInst )) { MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s - failed\n", dllname ); - Com_FreeLibrary( hInst ); + COM_FreeLibrary( hInst ); return NULL; } } @@ -809,12 +807,12 @@ void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolea return hInst; } -void *Com_LoadLibrary( const char *dllname, int build_ordinals_table ) +void *COM_LoadLibrary( const char *dllname, int build_ordinals_table ) { - return Com_LoadLibraryExt( dllname, build_ordinals_table, false ); + return COM_LoadLibraryExt( dllname, build_ordinals_table, false ); } -void *Com_GetProcAddress( void *hInstance, const char *name ) +void *COM_GetProcAddress( void *hInstance, const char *name ) { dll_user_t *hInst = (dll_user_t *)hInstance; @@ -826,7 +824,7 @@ void *Com_GetProcAddress( void *hInstance, const char *name ) return (void *)GetProcAddress( hInst->hInstance, GetMSVCName( name )); } -void Com_FreeLibrary( void *hInstance ) +void COM_FreeLibrary( void *hInstance ) { dll_user_t *hInst = (dll_user_t *)hInstance; @@ -852,7 +850,7 @@ void Com_FreeLibrary( void *hInstance ) Mem_Free( hInst ); // done } -dword Com_FunctionFromName( void *hInstance, const char *pName ) +dword COM_FunctionFromName( void *hInstance, const char *pName ) { dll_user_t *hInst = (dll_user_t *)hInstance; int i, index; @@ -872,7 +870,7 @@ dword Com_FunctionFromName( void *hInstance, const char *pName ) return 0; } -const char *Com_NameForFunction( void *hInstance, dword function ) +const char *COM_NameForFunction( void *hInstance, dword function ) { dll_user_t *hInst = (dll_user_t *)hInstance; int i, index; diff --git a/engine/common/library.h b/engine/common/library.h index 7b2b1503..0afe0e0b 100644 --- a/engine/common/library.h +++ b/engine/common/library.h @@ -151,11 +151,11 @@ typedef struct dll_user_s } dll_user_t; dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath ); -void *Com_LoadLibrary( const char *dllname, int build_ordinals_table ); -void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolean directpath ); -void *Com_GetProcAddress( void *hInstance, const char *name ); -const char *Com_NameForFunction( void *hInstance, dword function ); -dword Com_FunctionFromName( void *hInstance, const char *pName ); -void Com_FreeLibrary( void *hInstance ); +void *COM_LoadLibrary( const char *dllname, int build_ordinals_table ); +void *COM_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolean directpath ); +void *COM_GetProcAddress( void *hInstance, const char *name ); +const char *COM_NameForFunction( void *hInstance, dword function ); +dword COM_FunctionFromName( void *hInstance, const char *pName ); +void COM_FreeLibrary( void *hInstance ); #endif//LIBRARY_H \ No newline at end of file diff --git a/engine/common/mod_bmodel.c b/engine/common/mod_bmodel.c index e9aae678..325f712f 100644 --- a/engine/common/mod_bmodel.c +++ b/engine/common/mod_bmodel.c @@ -1236,7 +1236,7 @@ static qboolean Mod_LoadColoredLighting( dbspmodel_t *bmod ) size_t litdatasize; byte *in; - FS_FileBase( loadmodel->name, modelname ); + COM_FileBase( loadmodel->name, modelname ); Q_snprintf( path, sizeof( path ), "maps/%s.lit", modelname ); // make sure what deluxemap is actual @@ -1244,7 +1244,7 @@ static qboolean Mod_LoadColoredLighting( dbspmodel_t *bmod ) return false; if( iCompare < 0 ) // this may happens if level-designer used -onlyents key for hlcsg - MsgDev( D_WARN, "Mod_LoadColoredLighting: %s probably is out of date\n", path ); + MsgDev( D_WARN, "%s probably is out of date\n", path ); in = FS_LoadFile( path, &litdatasize, false ); @@ -1252,7 +1252,6 @@ static qboolean Mod_LoadColoredLighting( dbspmodel_t *bmod ) if( *(uint *)in != IDDELUXEMAPHEADER || *((uint *)in + 1) != DELUXEMAP_VERSION ) { - MsgDev( D_ERROR, "Mod_LoadColoredLighting: %s is not a lightmap file\n", path ); Mem_Free( in ); return false; } @@ -1260,7 +1259,6 @@ static qboolean Mod_LoadColoredLighting( dbspmodel_t *bmod ) // skip header bytes litdatasize -= 8; - MsgDev( D_INFO, "Mod_LoadColoredLighting: %s loaded\n", path ); loadmodel->lightdata = Mem_Alloc( loadmodel->mempool, litdatasize ); memcpy( loadmodel->lightdata, in + 8, litdatasize ); SetBits( loadmodel->flags, MODEL_COLORED_LIGHTING ); @@ -1286,7 +1284,7 @@ static void Mod_LoadDeluxemap( dbspmodel_t *bmod ) if( !FBitSet( host.features, ENGINE_LOAD_DELUXEDATA )) return; - FS_FileBase( loadmodel->name, modelname ); + COM_FileBase( loadmodel->name, modelname ); Q_snprintf( path, sizeof( path ), "maps/%s.dlit", modelname ); // make sure what deluxemap is actual @@ -1294,7 +1292,7 @@ static void Mod_LoadDeluxemap( dbspmodel_t *bmod ) return; if( iCompare < 0 ) // this may happens if level-designer used -onlyents key for hlcsg - MsgDev( D_WARN, "Mod_LoadDeluxemap: %s probably is out of date\n", path ); + MsgDev( D_WARN, "%s probably is out of date\n", path ); in = FS_LoadFile( path, &deluxdatasize, false ); @@ -1302,7 +1300,6 @@ static void Mod_LoadDeluxemap( dbspmodel_t *bmod ) if( *(uint *)in != IDDELUXEMAPHEADER || *((uint *)in + 1) != DELUXEMAP_VERSION ) { - MsgDev( D_ERROR, "Mod_LoadDeluxemap: %s is not a deluxemap file\n", path ); Mem_Free( in ); return; } @@ -1312,12 +1309,11 @@ static void Mod_LoadDeluxemap( dbspmodel_t *bmod ) if( deluxdatasize != bmod->lightdatasize ) { - MsgDev( D_ERROR, "Mod_LoadDeluxemap: %s has mismatched size (%i should be %i)\n", path, deluxdatasize, bmod->lightdatasize ); + MsgDev( D_ERROR, "%s has mismatched size (%i should be %i)\n", path, deluxdatasize, bmod->lightdatasize ); Mem_Free( in ); return; } - MsgDev( D_INFO, "Mod_LoadDeluxemap: %s loaded\n", path ); bmod->deluxedata_out = Mem_Alloc( loadmodel->mempool, deluxdatasize ); memcpy( bmod->deluxedata_out, in + 8, deluxdatasize ); bmod->deluxdatasize = deluxdatasize; @@ -1544,7 +1540,7 @@ static void Mod_LoadEntities( dbspmodel_t *bmod ) for( pszWadFile = strtok( wadstring, ";" ); pszWadFile != NULL; pszWadFile = strtok( NULL, ";" )) { COM_FixSlashes( pszWadFile ); - FS_FileBase( pszWadFile, token ); + COM_FileBase( pszWadFile, token ); // make sure what wad is really exist if( FS_FileExists( va( "%s.wad", token ), false )) @@ -1852,7 +1848,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6); if( custom_palette ) size += sizeof( short ) + 768; - Q_snprintf( texname, sizeof( texname ), "#%s.mip", mt->name ); + Q_snprintf( texname, sizeof( texname ), "#%s:%s.mip", loadstat.name, mt->name ); tx->gl_texturenum = GL_LoadTexture( texname, (byte *)mt, size, 0, filter ); } @@ -1867,7 +1863,7 @@ static void Mod_LoadTextures( dbspmodel_t *bmod ) // check for luma texture if( FBitSet( R_GetTexture( tx->gl_texturenum )->flags, TF_HAS_LUMA )) { - Q_snprintf( texname, sizeof( texname ), "#%s_luma.mip", mt->name ); + Q_snprintf( texname, sizeof( texname ), "#%s:%s_luma.mip", loadstat.name, mt->name ); if( mt->offsets[0] > 0 ) { @@ -2461,7 +2457,6 @@ static void Mod_LoadLightVecs( dbspmodel_t *bmod ) bmod->deluxedata_out = Mem_Alloc( loadmodel->mempool, bmod->deluxdatasize ); memcpy( bmod->deluxedata_out, bmod->deluxdata, bmod->deluxdatasize ); - MsgDev( D_INFO, "Mod_LoadLightVecs: loaded\n" ); } /* @@ -2480,7 +2475,6 @@ static void Mod_LoadShadowmap( dbspmodel_t *bmod ) bmod->shadowdata_out = Mem_Alloc( loadmodel->mempool, bmod->shadowdatasize ); memcpy( bmod->shadowdata_out, bmod->shadowdata, bmod->shadowdatasize ); - MsgDev( D_INFO, "Mod_LoadShadowmap: loaded\n" ); } /* @@ -2612,11 +2606,11 @@ qboolean Mod_LoadBmodelLumps( const byte *mod_base, qboolean isworld ) if( loadstat.numerrors ) { - MsgDev( D_INFO, "Mod_Load%s: %i error(s), %i warning(s)\n", isworld ? "World" : "Brush", loadstat.numerrors, loadstat.numwarnings ); + Con_DPrintf( "Mod_Load%s: %i error(s), %i warning(s)\n", isworld ? "World" : "Brush", loadstat.numerrors, loadstat.numwarnings ); return false; // there were errors, we can't load this map } else if( loadstat.numwarnings ) - MsgDev( D_INFO, "Mod_Load%s: %i warning(s)\n", isworld ? "World" : "Brush", loadstat.numwarnings ); + Con_DPrintf( "Mod_Load%s: %i warning(s)\n", isworld ? "World" : "Brush", loadstat.numwarnings ); // load into heap Mod_LoadEntities( bmod ); @@ -2697,13 +2691,13 @@ qboolean Mod_TestBmodelLumps( const char *name, const byte *mod_base, qboolean s if( loadstat.numerrors ) { if( !FBitSet( flags, LUMP_SILENT )) - MsgDev( D_INFO, "Mod_LoadWorld: %i error(s), %i warning(s)\n", loadstat.numerrors, loadstat.numwarnings ); + Con_Printf( "Mod_LoadWorld: %i error(s), %i warning(s)\n", loadstat.numerrors, loadstat.numwarnings ); return false; // there were errors, we can't load this map } else if( loadstat.numwarnings ) { if( !FBitSet( flags, LUMP_SILENT )) - MsgDev( D_INFO, "Mod_LoadWorld: %i warning(s)\n", loadstat.numwarnings ); + Con_Printf( "Mod_LoadWorld: %i warning(s)\n", loadstat.numwarnings ); } return true; diff --git a/engine/common/mod_local.h b/engine/common/mod_local.h index cbbe5895..a3859529 100644 --- a/engine/common/mod_local.h +++ b/engine/common/mod_local.h @@ -97,8 +97,6 @@ typedef struct typedef struct { - int load_sequence; // increace each map change - qboolean loading; // true if worldmodel is loading int flags; // misc flags @@ -148,7 +146,6 @@ qboolean Mod_ValidateCRC( const char *name, CRC32_t crc ); void Mod_NeedCRC( const char *name, qboolean needCRC ); void Mod_PurgeStudioCache( void ); void Mod_FreeUnused( void ); -void Mod_ClearAll( void ); // // mod_bmodel.c @@ -183,6 +180,8 @@ void R_StudioCalcBoneQuaternion( int frame, float s, void *pbone, void *panim, f void R_StudioCalcBonePosition( int frame, float s, void *pbone, void *panim, vec3_t adj, vec3_t pos ); void *R_StudioGetAnim( void *m_pStudioHeader, void *m_pSubModel, void *pseqdesc ); void Mod_StudioComputeBounds( void *buffer, vec3_t mins, vec3_t maxs, qboolean ignore_sequences ); +void Mod_StudioLoadTextures( model_t *mod, void *data ); +void Mod_StudioUnloadTextures( void *data ); int Mod_HitgroupForStudioHull( int index ); void Mod_ClearStudioCache( void ); diff --git a/engine/common/mod_studio.c b/engine/common/mod_studio.c index 7799e8b2..eb5b8341 100644 --- a/engine/common/mod_studio.c +++ b/engine/common/mod_studio.c @@ -720,6 +720,189 @@ qboolean Mod_GetStudioBounds( const char *name, vec3_t mins, vec3_t maxs ) return result; } +/* +=============== +Mod_StudioTexName + +extract texture filename from modelname +=============== +*/ +const char *Mod_StudioTexName( model_t *mod ) +{ + static char texname[MAX_QPATH]; + + Q_strncpy( texname, mod->name, sizeof( texname )); + COM_StripExtension( texname ); + Q_strncat( texname, "T.mdl", sizeof( texname )); + + return texname; +} + +/* +================ +Mod_StudioBodyVariations + +calc studio body variations +================ +*/ +static int Mod_StudioBodyVariations( model_t *mod ) +{ + studiohdr_t *pstudiohdr; + mstudiobodyparts_t *pbodypart; + int i, count = 1; + + pstudiohdr = (studiohdr_t *)Mod_StudioExtradata( mod ); + if( !pstudiohdr ) return 0; + + pbodypart = (mstudiobodyparts_t *)((byte *)pstudiohdr + pstudiohdr->bodypartindex); + + // each body part has nummodels variations so there are as many total variations as there + // are in a matrix of each part by each other part + for( i = 0; i < pstudiohdr->numbodyparts; i++ ) + count = count * pbodypart[i].nummodels; + + return count; +} + +/* +================= +R_StudioLoadHeader +================= +*/ +studiohdr_t *R_StudioLoadHeader( model_t *mod, const void *buffer ) +{ + byte *pin; + studiohdr_t *phdr; + int i; + + if( !buffer ) return NULL; + + pin = (byte *)buffer; + phdr = (studiohdr_t *)pin; + i = phdr->version; + + if( i != STUDIO_VERSION ) + { + MsgDev( D_ERROR, "%s has wrong version number (%i should be %i)\n", mod->name, i, STUDIO_VERSION ); + return NULL; + } + + return (studiohdr_t *)buffer; +} + +/* +================= +Mod_LoadStudioModel +================= +*/ +void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded ) +{ + studiohdr_t *phdr; + + if( loaded ) *loaded = false; + loadmodel->mempool = Mem_AllocPool( va( "^2%s^7", loadmodel->name )); + loadmodel->type = mod_studio; + + phdr = R_StudioLoadHeader( mod, buffer ); + if( !phdr ) return; // bad model + + if( phdr->numtextures == 0 ) + { + studiohdr_t *thdr; + byte *in, *out; + void *buffer2 = NULL; + size_t size1, size2; + + buffer2 = FS_LoadFile( Mod_StudioTexName( mod ), NULL, false ); + thdr = R_StudioLoadHeader( mod, buffer2 ); + + if( !thdr ) + { + MsgDev( D_WARN, "Mod_LoadStudioModel: %s missing textures file\n", mod->name ); + if( buffer2 ) Mem_Free( buffer2 ); + } + else + { + Mod_StudioLoadTextures( mod, thdr ); + + // give space for textures and skinrefs + size1 = thdr->numtextures * sizeof( mstudiotexture_t ); + size2 = thdr->numskinfamilies * thdr->numskinref * sizeof( short ); + mod->cache.data = Mem_Alloc( loadmodel->mempool, phdr->length + size1 + size2 ); + memcpy( loadmodel->cache.data, buffer, phdr->length ); // copy main mdl buffer + phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr + phdr->numskinfamilies = thdr->numskinfamilies; + phdr->numtextures = thdr->numtextures; + phdr->numskinref = thdr->numskinref; + phdr->textureindex = phdr->length; + phdr->skinindex = phdr->textureindex + size1; + + in = (byte *)thdr + thdr->textureindex; + out = (byte *)phdr + phdr->textureindex; + memcpy( out, in, size1 + size2 ); // copy textures + skinrefs + phdr->length += size1 + size2; + Mem_Free( buffer2 ); // release T.mdl + } + } + else + { + // NOTE: don't modify source buffer because it's used for CRC computing + loadmodel->cache.data = Mem_Alloc( loadmodel->mempool, phdr->length ); + memcpy( loadmodel->cache.data, buffer, phdr->length ); + phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr + Mod_StudioLoadTextures( mod, phdr ); + + // NOTE: we wan't keep raw textures in memory. just cutoff model pointer above texture base + loadmodel->cache.data = Mem_Realloc( loadmodel->mempool, loadmodel->cache.data, phdr->texturedataindex ); + phdr = (studiohdr_t *)loadmodel->cache.data; // get the new pointer on studiohdr + phdr->length = phdr->texturedataindex; // update model size + } + + // setup bounding box + if( !VectorCompare( vec3_origin, phdr->bbmin )) + { + // clipping bounding box + VectorCopy( phdr->bbmin, loadmodel->mins ); + VectorCopy( phdr->bbmax, loadmodel->maxs ); + } + else if( !VectorCompare( vec3_origin, phdr->min )) + { + // movement bounding box + VectorCopy( phdr->min, loadmodel->mins ); + VectorCopy( phdr->max, loadmodel->maxs ); + } + else + { + // well compute bounds from vertices and round to nearest even values + Mod_StudioComputeBounds( phdr, loadmodel->mins, loadmodel->maxs, true ); + RoundUpHullSize( loadmodel->mins ); + RoundUpHullSize( loadmodel->maxs ); + } + + loadmodel->numframes = Mod_StudioBodyVariations( loadmodel ); + loadmodel->radius = RadiusFromBounds( loadmodel->mins, loadmodel->maxs ); + loadmodel->flags = phdr->flags; // copy header flags + + if( loaded ) *loaded = true; +} + +/* +================= +Mod_UnloadStudioModel +================= +*/ +void Mod_UnloadStudioModel( model_t *mod ) +{ + Assert( mod != NULL ); + + if( mod->type != mod_studio ) + return; // not a studio + + Mod_StudioUnloadTextures( mod->cache.data ); + Mem_FreePool( &mod->mempool ); + memset( mod, 0, sizeof( *mod )); +} + static sv_blending_interface_t gBlendAPI = { SV_BLENDING_INTERFACE_VERSION, @@ -747,7 +930,7 @@ void Mod_InitStudioAPI( void ) pBlendAPI = &gBlendAPI; - pBlendIface = (STUDIOAPI)Com_GetProcAddress( svgame.hInstance, "Server_GetBlendingInterface" ); + pBlendIface = (STUDIOAPI)COM_GetProcAddress( svgame.hInstance, "Server_GetBlendingInterface" ); if( pBlendIface && pBlendIface( SV_BLENDING_INTERFACE_VERSION, &pBlendAPI, &gStudioAPI, &studio_transform, &studio_bones )) { MsgDev( D_REPORT, "SV_LoadProgs: ^2initailized Server Blending interface ^7ver. %i\n", SV_BLENDING_INTERFACE_VERSION ); diff --git a/engine/common/model.c b/engine/common/model.c index dd19d8b4..756f99fc 100644 --- a/engine/common/model.c +++ b/engine/common/model.c @@ -50,21 +50,20 @@ static void Mod_Modellist_f( void ) int i, nummodels; model_t *mod; - Msg( "\n" ); - Msg( "-----------------------------------\n" ); + Con_Printf( "\n" ); + Con_Printf( "-----------------------------------\n" ); for( i = nummodels = 0, mod = mod_known; i < mod_numknown; i++, mod++ ) { if( !mod->name[0] ) continue; // free slot - - Msg( "%s%s\n", mod->name, (mod->type == mod_bad) ? " (DEFAULTED)" : "" ); + Con_Printf( "%s\n", mod->name ); nummodels++; } - Msg( "-----------------------------------\n" ); - Msg( "%i total models\n", nummodels ); - Msg( "\n" ); + Con_Printf( "-----------------------------------\n" ); + Con_Printf( "%i total models\n", nummodels ); + Con_Printf( "\n" ); } /* @@ -164,23 +163,6 @@ void Mod_FreeAll( void ) mod_numknown = 0; } -/* -================ -Mod_ClearAll - -clear all models as unreferenced -but don't touch the real data -================ -*/ -void Mod_ClearAll( void ) -{ - model_t *mod; - int i; - - for( i = 0, mod = mod_known; i < mod_numknown; i++, mod++ ) - mod->needload = NL_UNREFERENCED; -} - /* ================ Mod_ClearUserData @@ -234,7 +216,7 @@ model_t *Mod_FindName( const char *filename, qboolean trackCRC ) { if( !Q_stricmp( mod->name, modname )) { - if( mod->mempool ) + if( mod->mempool || mod->name[0] == '*' ) mod->needload = NL_PRESENT; else mod->needload = NL_NEEDS_LOADED; @@ -257,6 +239,7 @@ model_t *Mod_FindName( const char *filename, qboolean trackCRC ) Q_strncpy( mod->name, modname, sizeof( mod->name )); if( trackCRC ) mod_crcinfo[i].flags = FCRC_SHOULD_CHECKSUM; else mod_crcinfo[i].flags = 0; + mod->needload = NL_NEEDS_LOADED; mod_crcinfo[i].initialCRC = 0; return mod; @@ -291,6 +274,8 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ) return mod; } + ASSERT( mod->needload == NL_NEEDS_LOADED ); + // store modelname to show error Q_strncpy( tempname, mod->name, sizeof( tempname )); COM_FixSlashes( tempname ); @@ -307,8 +292,8 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash ) return NULL; } - MsgDev( D_NOTE, "Mod_LoadModel: %s\n", mod->name ); - mod->needload = world.load_sequence; // register mod + Con_DPrintf( "loading %s\n", mod->name ); + mod->needload = NL_PRESENT; mod->type = mod_bad; loadmodel = mod; @@ -425,6 +410,7 @@ void Mod_PurgeStudioCache( void ) mod_known[i].submodels = NULL; if( mod_known[i].name[0] == '*' ) Mod_FreeModel( &mod_known[i] ); + mod_known[i].needload = NL_UNREFERENCED; } Mem_EmptyPool( com_studiocache ); @@ -452,9 +438,6 @@ model_t *Mod_LoadWorld( const char *name, qboolean preload ) // release previois map Mod_FreeModel( mod_known ); // world is stuck on slot #0 always - world.load_sequence++; // now all models are invalid - Mod_ClearAll(); - // load the newmap world.loading = true; pworld = Mod_FindName( name, false ); @@ -480,7 +463,7 @@ void Mod_FreeUnused( void ) for( i = 0, mod = mod_known; i < mod_numknown; i++, mod++ ) { - if( mod->needload == NL_UNREFERENCED ) + if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name )) Mod_FreeModel( mod ); } } diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 18c70a90..d715662b 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -143,7 +143,7 @@ void Netchan_ReportFlow( netchan_t *chan ) Q_strcpy( incoming, Q_pretifymem((float)chan->flow[FLOW_INCOMING].totalbytes, 3 )); Q_strcpy( outgoing, Q_pretifymem((float)chan->flow[FLOW_OUTGOING].totalbytes, 3 )); - MsgDev( D_INFO, "Signon network traffic: %s from server, %s to server\n", incoming, outgoing ); + Con_DPrintf( "Signon network traffic: %s from server, %s to server\n", incoming, outgoing ); } /* diff --git a/engine/common/net_ws.c b/engine/common/net_ws.c index 0520b1eb..1a37ead6 100644 --- a/engine/common/net_ws.c +++ b/engine/common/net_ws.c @@ -653,7 +653,7 @@ static void NET_AdjustLag( void ) dt = bound( 0.0, dt, 0.1 ); lasttime = host.realtime; - if( host.developer >= D_ERROR || !net_fakelag->value ) + if( host.developer || !net_fakelag->value ) { if( net_fakelag->value != net.fakelag ) { @@ -668,7 +668,7 @@ static void NET_AdjustLag( void ) } else { - MsgDev( D_INFO, "Server must enable dev-mode to activate fakelag\n" ); + Con_Printf( "Server must enable dev-mode to activate fakelag\n" ); Cvar_SetValue( "fakelag", 0.0 ); net.fakelag = 0.0f; } @@ -1181,8 +1181,7 @@ NET_OpenIP */ static void NET_OpenIP( void ) { - int port, sv_port = 0, cl_port = 0; - static qboolean bFirst = true; + int port, sv_port = 0, cl_port = 0; if( net.ip_sockets[NS_SERVER] == INVALID_SOCKET ) { @@ -1210,12 +1209,6 @@ static void NET_OpenIP( void ) net.ip_sockets[NS_CLIENT] = NET_IPSocket( net_ipname->string, PORT_ANY, false ); cl_port = port; } - - if( bFirst ) - { - MsgDev( D_INFO, "NET Ports: server %i, client %i\n", sv_port, cl_port ); - bFirst = false; - } } /* @@ -1261,7 +1254,7 @@ void NET_GetLocalAddress( void ) else { net_local.port = address.sin_port; - Msg( "Server IP address %s\n", NET_AdrToString( net_local )); + Con_Printf( "Server IP address %s\n", NET_AdrToString( net_local )); Cvar_FullSet( "net_address", va( NET_AdrToString( net_local )), FCVAR_READ_ONLY ); } } @@ -1272,7 +1265,7 @@ void NET_GetLocalAddress( void ) } else { - MsgDev( D_INFO, "TCP/IP Disabled.\n" ); + Con_Printf( "TCP/IP Disabled.\n" ); } } @@ -1428,9 +1421,7 @@ void NET_Init( void ) return; } - i = pWSAStartup( MAKEWORD( 1, 1 ), &net.winsockdata ); - - if( i ) + if( pWSAStartup( MAKEWORD( 1, 1 ), &net.winsockdata )) { MsgDev( D_ERROR, "network initialization failed.\n" ); NET_FreeWinSock(); diff --git a/engine/common/protocol.h b/engine/common/protocol.h index ca30c10a..15e5ac0e 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -23,7 +23,7 @@ GNU General Public License for more details. #define svc_nop 1 // does nothing #define svc_disconnect 2 // kick client from server #define svc_event 3 // playback event queue -#define svc_changing 4 // changelevel by server request +#define svc_version 4 // [long] server version #define svc_setview 5 // [short] entity number #define svc_sound 6 // #define svc_time 7 // [float] server time diff --git a/engine/common/soundlib/snd_main.c b/engine/common/soundlib/snd_main.c index ce0baac4..8fd6d70a 100644 --- a/engine/common/soundlib/snd_main.c +++ b/engine/common/soundlib/snd_main.c @@ -56,7 +56,7 @@ loading and unpack to wav any known sound */ wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size ) { - const char *ext = FS_FileExtension( filename ); + const char *ext = COM_FileExtension( filename ); string path, loadname; qboolean anyformat = true; int filesize = 0; @@ -74,7 +74,7 @@ wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size ) { if( !Q_stricmp( format->ext, ext )) { - FS_StripExtension( loadname ); + COM_StripExtension( loadname ); anyformat = false; break; } @@ -150,7 +150,7 @@ open and reading basic info from sound stream */ stream_t *FS_OpenStream( const char *filename ) { - const char *ext = FS_FileExtension( filename ); + const char *ext = COM_FileExtension( filename ); string path, loadname; qboolean anyformat = true; const streamfmt_t *format; @@ -167,7 +167,7 @@ stream_t *FS_OpenStream( const char *filename ) { if( !Q_stricmp( format->ext, ext )) { - FS_StripExtension( loadname ); + COM_StripExtension( loadname ); anyformat = false; break; } diff --git a/engine/engine.dsp b/engine/engine.dsp index 809c6df8..0f5b2b61 100644 --- a/engine/engine.dsp +++ b/engine/engine.dsp @@ -587,6 +587,10 @@ SOURCE=.\client\client.h # End Source File # Begin Source File +SOURCE=.\common\com_strings.h +# End Source File +# Begin Source File + SOURCE=.\common\common.h # End Source File # Begin Source File diff --git a/engine/server/server.h b/engine/server/server.h index 8ab1f7f1..b21298e9 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -136,10 +136,11 @@ typedef struct server_s double time; // sv.time += sv.frametime double time_residual; // unclamped float frametime; // 1.0 / sv_fps->value - int net_framenum; // to avoid send edicts twice through portals + int framecount; // count physic frames int hostflags; // misc server flags: predicting etc CRC32_t worldmapCRC; + int progsCRC; string name; // map name string startspot; // player_start name on nextmap @@ -378,7 +379,6 @@ typedef struct char serverinfo[MAX_SERVERINFO_STRING]; char localinfo[MAX_LOCALINFO_STRING]; - double changelevel_next_time; // don't execute multiple changelevels at once time int spawncount; // incremented each server start // used to check late spawns sv_client_t *clients; // [svs.maxclients] @@ -458,7 +458,7 @@ extern convar_t *public_server; // // sv_main.c // -void SV_FinalMessage( char *message, qboolean reconnect ); +void SV_FinalMessage( const char *message, qboolean reconnect ); void SV_DropClient( sv_client_t *drop ); void SV_UpdateMovevars( qboolean initialize ); int SV_ModelIndex( const char *name ); @@ -638,7 +638,7 @@ _inline edict_t *SV_EDICT_NUM( int n, const char * file, const int line ) void Log_Close( void ); void Log_Open( void ); void Log_PrintServerVars( void ); -void SV_ServerLog_f( sv_client_t *cl ); +qboolean SV_ServerLog_f( sv_client_t *cl ); // // sv_save.c diff --git a/engine/server/sv_client.c b/engine/server/sv_client.c index 35838c93..d3860e6b 100644 --- a/engine/server/sv_client.c +++ b/engine/server/sv_client.c @@ -37,7 +37,7 @@ const char *clc_strings[clc_lastmsg+1] = typedef struct ucmd_s { const char *name; - void (*func)( sv_client_t *cl ); + qboolean (*func)( sv_client_t *cl ); } ucmd_t; static int g_userid = 1; @@ -1404,7 +1404,7 @@ void SV_SendServerdata( sizebuf_t *msg, sv_client_t *cl ) if(( host.developer ) || ( svs.maxclients > 1 )) { MSG_BeginServerCmd( msg, svc_print ); - Q_snprintf( message, sizeof( message ), "%c\nBUILD %d SERVER (%i CRC)\nServer # %i\n", 2, Q_buildnum(), 0, svs.spawncount ); + Q_snprintf( message, sizeof( message ), "%c\nBUILD %d SERVER (%i CRC)\nServer # %i\n", 2, Q_buildnum(), sv.progsCRC, svs.spawncount ); MSG_WriteString( msg, message ); } @@ -1468,7 +1468,7 @@ Sends the first message from the server to a connected client. This will be sent on the initial connection and upon each server load. ================ */ -void SV_New_f( sv_client_t *cl ) +static qboolean SV_New_f( sv_client_t *cl ) { byte msg_buf[MAX_INIT_MSG]; sv_client_t *cur; @@ -1478,10 +1478,7 @@ void SV_New_f( sv_client_t *cl ) MSG_Init( &msg, "New", msg_buf, sizeof( msg_buf )); if( cl->state != cs_connected ) - { - MsgDev( D_INFO, "'new' is not valid from the console\n" ); - return; - } + return false; // send the serverdata SV_SendServerdata( &msg, cl ); @@ -1503,6 +1500,8 @@ void SV_New_f( sv_client_t *cl ) Netchan_CreateFragments( &cl->netchan, &msg ); Netchan_FragSend( &cl->netchan ); + + return true; } /* @@ -1510,23 +1509,19 @@ void SV_New_f( sv_client_t *cl ) SV_WriteModels_f ================== */ -void SV_WriteModels_f( sv_client_t *cl ) +static qboolean SV_WriteModels_f( sv_client_t *cl ) { int start; string cmd; if( cl->state != cs_connected ) - { - MsgDev( D_INFO, "'modellist' is not valid from the console\n" ); - return; - } + return false; // handle the case of a level changing while a client was connecting if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount ) { - MsgDev( D_INFO, "'modellist' from different level\n" ); SV_New_f( cl ); - return; + return true; } start = Q_atoi( Cmd_Argv( 2 )); @@ -1549,6 +1544,8 @@ void SV_WriteModels_f( sv_client_t *cl ) // send next command MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext ); MSG_WriteString( &cl->netchan.message, cmd ); + + return true; } /* @@ -1556,23 +1553,19 @@ void SV_WriteModels_f( sv_client_t *cl ) SV_WriteSounds_f ================== */ -void SV_WriteSounds_f( sv_client_t *cl ) +static qboolean SV_WriteSounds_f( sv_client_t *cl ) { int start; string cmd; if( cl->state != cs_connected ) - { - MsgDev( D_INFO, "'soundlist' is not valid from the console\n" ); - return; - } + return false; // handle the case of a level changing while a client was connecting if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount ) { - MsgDev( D_INFO, "'soundlist' from different level\n" ); SV_New_f( cl ); - return; + return true; } start = Q_atoi( Cmd_Argv( 2 )); @@ -1595,6 +1588,8 @@ void SV_WriteSounds_f( sv_client_t *cl ) // send next command MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext ); MSG_WriteString( &cl->netchan.message, cmd ); + + return true; } /* @@ -1602,23 +1597,19 @@ void SV_WriteSounds_f( sv_client_t *cl ) SV_WriteEvents_f ================== */ -void SV_WriteEvents_f( sv_client_t *cl ) +static qboolean SV_WriteEvents_f( sv_client_t *cl ) { int start; string cmd; if( cl->state != cs_connected ) - { - MsgDev( D_INFO, "'eventlist' is not valid from the console\n" ); - return; - } + return false; // handle the case of a level changing while a client was connecting if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount ) { - MsgDev( D_INFO, "'eventlist' from different level\n" ); SV_New_f( cl ); - return; + return true; } start = Q_atoi( Cmd_Argv( 2 )); @@ -1641,6 +1632,8 @@ void SV_WriteEvents_f( sv_client_t *cl ) // send next command MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext ); MSG_WriteString( &cl->netchan.message, cmd ); + + return true; } /* @@ -1650,9 +1643,10 @@ SV_Disconnect_f The client is going to disconnect, so remove the connection immediately ================= */ -void SV_Disconnect_f( sv_client_t *cl ) +static qboolean SV_Disconnect_f( sv_client_t *cl ) { SV_DropClient( cl ); + return true; } /* @@ -1662,9 +1656,10 @@ SV_ShowServerinfo_f Dumps the serverinfo info string ================== */ -void SV_ShowServerinfo_f( sv_client_t *cl ) +static qboolean SV_ShowServerinfo_f( sv_client_t *cl ) { Info_Print( svs.serverinfo ); + return true; } /* @@ -1672,30 +1667,32 @@ void SV_ShowServerinfo_f( sv_client_t *cl ) SV_Pause_f ================== */ -void SV_Pause_f( sv_client_t *cl ) +static qboolean SV_Pause_f( sv_client_t *cl ) { string message; - if( UI_CreditsActive( )) return; + if( UI_CreditsActive( )) + return true; if( !sv_pausable->value ) { SV_ClientPrintf( cl, "Pause not allowed.\n" ); - return; + return true; } if( FBitSet( cl->flags, FCL_HLTV_PROXY )) { SV_ClientPrintf( cl, "Spectators can not pause.\n" ); - return; + return true; } if( !sv.paused ) Q_snprintf( message, MAX_STRING, "^2%s^7 paused the game\n", cl->name ); else Q_snprintf( message, MAX_STRING, "^2%s^7 unpaused the game\n", cl->name ); SV_TogglePause( message ); -} + return true; +} /* ================= @@ -1713,7 +1710,8 @@ void SV_UserinfoChanged( sv_client_t *cl, const char *userinfo ) sv_client_t *current; char *val; - if( !userinfo || !userinfo[0] ) return; // ignored + if( !COM_CheckString( userinfo )) + return; val = Info_ValueForKey( cl->userinfo, "name" ); Q_strncpy( name2, val, sizeof( name2 )); @@ -1812,12 +1810,13 @@ void SV_UserinfoChanged( sv_client_t *cl, const char *userinfo ) SV_UpdateUserinfo_f ================== */ -static void SV_UpdateUserinfo_f( sv_client_t *cl ) +static qboolean SV_UpdateUserinfo_f( sv_client_t *cl ) { Q_strncpy( cl->userinfo, Cmd_Argv( 1 ), sizeof( cl->userinfo )); if( cl->state >= cs_connected ) SetBits( cl->flags, FCL_RESEND_USERINFO ); // needs for update client info + return true; } /* @@ -1825,12 +1824,13 @@ static void SV_UpdateUserinfo_f( sv_client_t *cl ) SV_SetInfo_f ================== */ -static void SV_SetInfo_f( sv_client_t *cl ) +static qboolean SV_SetInfo_f( sv_client_t *cl ) { Info_SetValueForKey( cl->userinfo, Cmd_Argv( 1 ), Cmd_Argv( 2 ), MAX_INFO_STRING ); if( cl->state >= cs_connected ) SetBits( cl->flags, FCL_RESEND_USERINFO ); // needs for update client info + return true; } /* @@ -1838,12 +1838,12 @@ static void SV_SetInfo_f( sv_client_t *cl ) SV_Noclip_f ================== */ -static void SV_Noclip_f( sv_client_t *cl ) +static qboolean SV_Noclip_f( sv_client_t *cl ) { edict_t *pEntity = cl->edict; if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background ) - return; + return true; if( pEntity->v.movetype != MOVETYPE_NOCLIP ) { @@ -1855,30 +1855,8 @@ static void SV_Noclip_f( sv_client_t *cl ) SV_ClientPrintf( cl, "noclip OFF\n" ); pEntity->v.movetype = MOVETYPE_WALK; } -} -/* -================== -SV_Fly_f -================== -*/ -static void SV_Fly_f( sv_client_t *cl ) -{ - edict_t *pEntity = cl->edict; - - if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background ) - return; - - if( pEntity->v.movetype != MOVETYPE_FLY ) - { - SV_ClientPrintf( cl, "flymode ON\n" ); - pEntity->v.movetype = MOVETYPE_FLY; - } - else - { - SV_ClientPrintf( cl, "flymode OFF\n" ); - pEntity->v.movetype = MOVETYPE_WALK; - } + return true; } /* @@ -1886,18 +1864,20 @@ static void SV_Fly_f( sv_client_t *cl ) SV_Godmode_f ================== */ -static void SV_Godmode_f( sv_client_t *cl ) +static qboolean SV_Godmode_f( sv_client_t *cl ) { edict_t *pEntity = cl->edict; if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background ) - return; + return true; pEntity->v.flags = pEntity->v.flags ^ FL_GODMODE; if( !FBitSet( pEntity->v.flags, FL_GODMODE )) SV_ClientPrintf( cl, "godmode OFF\n" ); else SV_ClientPrintf( cl, "godmode ON\n" ); + + return true; } /* @@ -1905,18 +1885,20 @@ static void SV_Godmode_f( sv_client_t *cl ) SV_Notarget_f ================== */ -static void SV_Notarget_f( sv_client_t *cl ) +static qboolean SV_Notarget_f( sv_client_t *cl ) { edict_t *pEntity = cl->edict; if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background ) - return; + return true; pEntity->v.flags = pEntity->v.flags ^ FL_NOTARGET; if( !FBitSet( pEntity->v.flags, FL_NOTARGET )) SV_ClientPrintf( cl, "notarget OFF\n" ); else SV_ClientPrintf( cl, "notarget ON\n" ); + + return true; } /* @@ -1924,27 +1906,26 @@ static void SV_Notarget_f( sv_client_t *cl ) SV_SendRes_f ================== */ -void SV_SendRes_f( sv_client_t *cl ) +static qboolean SV_SendRes_f( sv_client_t *cl ) { byte buffer[MAX_INIT_MSG]; sizebuf_t msg; if( cl->state != cs_connected ) - { - MsgDev( D_INFO, "'sendres' is not valid from the console\n" ); - return; - } + return false; MSG_Init( &msg, "SendResources", buffer, sizeof( buffer )); if( svs.maxclients > 1 && FBitSet( cl->flags, FCL_SEND_RESOURCES )) - return; + return true; SetBits( cl->flags, FCL_SEND_RESOURCES ); SV_SendResources( cl, &msg ); Netchan_CreateFragments( &cl->netchan, &msg ); Netchan_FragSend( &cl->netchan ); + + return true; } /* @@ -1952,23 +1933,22 @@ void SV_SendRes_f( sv_client_t *cl ) SV_DownloadFile_f ================== */ -void SV_DownloadFile_f( sv_client_t *cl ) +static qboolean SV_DownloadFile_f( sv_client_t *cl ) { - char *name; - char szModuleC[20] = "!ModuleC.dll"; + char *name; if( Cmd_Argc() < 2 ) - return; + return true; name = Cmd_Argv( 1 ); - if( !name || !name[0] ) - return; + if( !COM_CheckString( name )) + return true; if( !COM_IsSafeFileToDownload( name ) || !sv_allow_download.value ) { SV_FailDownload( cl, name ); - return; + return true; } if( cl->state == cs_spawned ) @@ -1976,7 +1956,7 @@ void SV_DownloadFile_f( sv_client_t *cl ) if( name[0] != '!' ) { SV_FailDownload( cl, name ); - return; + return true; } } else @@ -1988,12 +1968,12 @@ void SV_DownloadFile_f( sv_client_t *cl ) if( Netchan_CreateFileFragments( &cl->netchan, name )) { Netchan_FragSend( &cl->netchan ); - return; + return true; } } SV_FailDownload( cl, name ); - return; + return true; } } @@ -2024,6 +2004,8 @@ void SV_DownloadFile_f( sv_client_t *cl ) { SV_FailDownload( cl, name ); } + + return true; } /* @@ -2031,20 +2013,16 @@ void SV_DownloadFile_f( sv_client_t *cl ) SV_Spawn_f ================== */ -void SV_Spawn_f( sv_client_t *cl ) +static qboolean SV_Spawn_f( sv_client_t *cl ) { if( cl->state != cs_connected ) - { - MsgDev( D_INFO, "'spawn' is not valid from the console\n" ); - return; - } + return false; // handle the case of a level changing while a client was connecting if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount ) { - Msg( "'spawn' from different level\n" ); SV_New_f( cl ); - return; + return true; } SV_PutClientInServer( cl ); @@ -2056,6 +2034,7 @@ void SV_Spawn_f( sv_client_t *cl ) MSG_WriteByte( &sv.reliable_datagram, sv.paused ); SV_ClientPrintf( cl, "Server is paused.\n" ); } + return true; } /* @@ -2063,22 +2042,19 @@ void SV_Spawn_f( sv_client_t *cl ) SV_Begin_f ================== */ -void SV_Begin_f( sv_client_t *cl ) +static qboolean SV_Begin_f( sv_client_t *cl ) { if( cl->state != cs_connected ) - { - MsgDev( D_INFO, "'begin' is not valid from the console\n" ); - return; - } + return false; // now client is spawned cl->state = cs_spawned; + return true; } ucmd_t ucmds[] = { { "new", SV_New_f }, -{ "fly", SV_Fly_f }, { "god", SV_Godmode_f }, { "begin", SV_Begin_f }, { "spawn", SV_Spawn_f }, @@ -2116,8 +2092,9 @@ void SV_ExecuteClientCommand( sv_client_t *cl, char *s ) { if( !Q_strcmp( Cmd_Argv( 0 ), u->name )) { - MsgDev( D_NOTE, "ucmd->%s()\n", u->name ); - if( u->func ) u->func( cl ); + if( !u->func( cl )) + Con_Printf( "'%s' is not valid from the console\n", u->name ); + else MsgDev( D_NOTE, "ucmd->%s()\n", u->name ); break; } } diff --git a/engine/server/sv_cmds.c b/engine/server/sv_cmds.c index 8c757249..a0070611 100644 --- a/engine/server/sv_cmds.c +++ b/engine/server/sv_cmds.c @@ -53,28 +53,27 @@ void SV_BroadcastPrintf( sv_client_t *ignore, char *fmt, ... ) sv_client_t *cl; int i; - if( sv.state == ss_dead ) - return; - va_start( argptr, fmt ); Q_vsprintf( string, fmt, argptr ); va_end( argptr ); - // echo to console - if( host.type == HOST_DEDICATED ) Msg( "%s", string ); - for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ ) + if( sv.state == ss_active ) { - if( FBitSet( cl->flags, FCL_FAKECLIENT )) - continue; + for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ ) + { + if( FBitSet( cl->flags, FCL_FAKECLIENT )) + continue; - if( cl == ignore || cl->state != cs_spawned ) - continue; + if( cl == ignore || cl->state != cs_spawned ) + continue; - MSG_BeginServerCmd( &cl->netchan.message, svc_print ); - MSG_WriteString( &cl->netchan.message, string ); + MSG_BeginServerCmd( &cl->netchan.message, svc_print ); + MSG_WriteString( &cl->netchan.message, string ); + } } + // echo to console MsgDev( D_REPORT, string ); } @@ -230,7 +229,7 @@ void SV_Map_f( void ) // hold mapname to other place Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); - FS_StripExtension( mapname ); + COM_StripExtension( mapname ); if( !SV_ValidateMap( mapname, true )) return; @@ -264,7 +263,7 @@ void SV_MapBackground_f( void ) // hold mapname to other place Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); - FS_StripExtension( mapname ); + COM_StripExtension( mapname ); if( !SV_ValidateMap( mapname, false )) return; @@ -417,105 +416,6 @@ void SV_AutoSave_f( void ) SV_SaveGame( "autosave" ); } -/* -================== -SV_ChangeLevel_f - -Saves the state of the map just being exited and goes to a new map. -================== -*/ -void SV_ChangeLevel_f( void ) -{ - string mapname; - char *spawn_entity; - int flags, c = Cmd_Argc(); - - if( c < 2 ) - { - Msg( "Usage: changelevel [landmark]\n" ); - return; - } - - // hold mapname to other place - Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); - FS_StripExtension( mapname ); - - // determine spawn entity classname - if( svs.maxclients == 1 ) - spawn_entity = GI->sp_entity; - else spawn_entity = GI->mp_entity; - - flags = SV_MapIsValid( mapname, spawn_entity, Cmd_Argv( 2 )); - - if( FBitSet( flags, MAP_INVALID_VERSION )) - { - MsgDev( D_ERROR, "map %s is invalid or not supported\n", mapname ); - return; - } - - if( !FBitSet( flags, MAP_IS_EXIST )) - { - MsgDev( D_ERROR, "map %s doesn't exist\n", mapname ); - return; - } - - if( c >= 3 && !FBitSet( flags, MAP_HAS_LANDMARK )) - { - if( sv_validate_changelevel->value ) - { - // NOTE: we find valid map but specified landmark it's doesn't exist - // run simple changelevel like in q1, throw warning - MsgDev( D_WARN, "map %s is exist but doesn't contain landmark with name %s. smooth transition disabled\n", - mapname, Cmd_Argv( 2 )); - c = 2; // reduce args - } - } - - if( c >= 3 && !Q_stricmp( sv.name, Cmd_Argv( 1 ))) - { - MsgDev( D_ERROR, "can't changelevel with same map. Ignored.\n" ); - return; - } - - if( c == 2 && !FBitSet( flags, MAP_HAS_SPAWNPOINT )) - { - if( sv_validate_changelevel->value ) - { - MsgDev( D_ERROR, "map %s doesn't have a valid spawnpoint. Ignored.\n", mapname ); - return; - } - } - - // bad changelevel position invoke enables in one-way transition - if( sv.net_framenum < 15 ) - { - if( sv_validate_changelevel->value ) - { - MsgDev( D_WARN, "an infinite changelevel detected and will be disabled until a next save\\restore\n" ); - return; // lock with svs.spawncount here - } - } - - if( sv.state != ss_active ) - { - MsgDev( D_ERROR, "only the server may changelevel\n" ); - return; - } - - if( sv.background ) - { - COM_LoadLevel( mapname, false ); - } - else - { - // g-cont: inactivate clients to avoid fired "trigger_changelevel" multiple times - SV_InactivateClients (); - - if( c == 2 ) COM_ChangeLevel( Cmd_Argv( 1 ), NULL ); - else COM_ChangeLevel( Cmd_Argv( 1 ), Cmd_Argv( 2 )); - } -} - /* ================== SV_Restart_f @@ -817,12 +717,7 @@ Kick everyone off, possibly in preparation for a new game */ void SV_KillServer_f( void ) { - if( !svs.initialized ) - return; - - Q_strncpy( host.finalmsg, "Server was killed", MAX_STRING ); - SV_Shutdown( false ); - NET_Config ( false ); // close network sockets + Host_ShutdownServer(); } /* @@ -917,7 +812,6 @@ is available always void SV_InitHostCommands( void ) { Cmd_AddCommand( "map", SV_Map_f, "start new level" ); - Cmd_AddCommand( "changelevel", SV_ChangeLevel_f, "changing level" ); if( host.type == HOST_NORMAL ) { diff --git a/engine/server/sv_frame.c b/engine/server/sv_frame.c index b0e0c8af..9042dc33 100644 --- a/engine/server/sv_frame.c +++ b/engine/server/sv_frame.c @@ -602,7 +602,6 @@ void SV_WriteEntitiesToClient( sv_client_t *cl, sizebuf_t *msg ) memset( frame_ents.sended, 0, sizeof( frame_ents.sended )); ClearBits( sv.hostflags, SVF_MERGE_VISIBILITY ); - sv.net_framenum++; // now all portal-through entities are invalidate // clear everything in this snapshot frame_ents.num_entities = c_fullsend = c_notsend = 0; diff --git a/engine/server/sv_game.c b/engine/server/sv_game.c index f9e3e9df..bfbf1a11 100644 --- a/engine/server/sv_game.c +++ b/engine/server/sv_game.c @@ -863,7 +863,7 @@ edict_t *SV_AllocEdict( void ) LINK_ENTITY_FUNC SV_GetEntityClass( const char *pszClassName ) { // allocate edict private memory (passed by dlls) - return (LINK_ENTITY_FUNC)Com_GetProcAddress( svgame.hInstance, pszClassName ); + return (LINK_ENTITY_FUNC)COM_GetProcAddress( svgame.hInstance, pszClassName ); } edict_t* SV_AllocPrivateData( edict_t *ent, string_t className ) @@ -1132,29 +1132,91 @@ pfnChangeLevel ================= */ -void pfnChangeLevel( const char* s1, const char* s2 ) +void pfnChangeLevel( const char *level, const char *landmark ) { + int flags, smooth = false; static uint last_spawncount = 0; + char mapname[MAX_QPATH]; + char *spawn_entity; - if( !s1 || s1[0] <= ' ' || sv.background ) - return; - - // make sure we don't issue two changelevels at one time - if( svs.changelevel_next_time > host.realtime ) - return; - - svs.changelevel_next_time = host.realtime + 0.5f; // rest 0.5f secs if failed + if( !COM_CheckString( level ) || sv.state != ss_active ) + return; // ??? // make sure we don't issue two changelevels if( svs.spawncount == last_spawncount ) return; - last_spawncount = svs.spawncount; + // hold mapname to other place + Q_strncpy( mapname, level, sizeof( mapname )); + COM_StripExtension( mapname ); + + if( COM_CheckString( landmark )) + smooth = true; + + // determine spawn entity classname + if( svs.maxclients == 1 ) + spawn_entity = GI->sp_entity; + else spawn_entity = GI->mp_entity; + + flags = SV_MapIsValid( mapname, spawn_entity, landmark ); + + if( FBitSet( flags, MAP_INVALID_VERSION )) + { + MsgDev( D_ERROR, "changelevel: %s is invalid or not supported\n", mapname ); + return; + } + + if( !FBitSet( flags, MAP_IS_EXIST )) + { + MsgDev( D_ERROR, "changelevel: map %s doesn't exist\n", mapname ); + return; + } + + if( smooth && !FBitSet( flags, MAP_HAS_LANDMARK )) + { + if( sv_validate_changelevel->value ) + { + // NOTE: we find valid map but specified landmark it's doesn't exist + // run simple changelevel like in q1, throw warning + MsgDev( D_WARN, "changelevel: %s doesn't contain landmark [%s]. smooth transition was disabled\n", mapname, landmark ); + smooth = false; + } + } + + if( svs.maxclients > 1 ) + smooth = false; // multiplayer doesn't support smooth transition + + if( smooth && !Q_stricmp( sv.name, level )) + { + MsgDev( D_ERROR, "can't changelevel with same map. Ignored.\n" ); + return; + } + + if( !smooth && !FBitSet( flags, MAP_HAS_SPAWNPOINT )) + { + if( sv_validate_changelevel->value ) + { + MsgDev( D_ERROR, "changelevel: %s doesn't have a valid spawnpoint. Ignored.\n", mapname ); + return; + } + } + + // bad changelevel position invoke enables in one-way transition + if( sv.framecount < 15 ) + { + if( sv_validate_changelevel->value ) + { + MsgDev( D_WARN, "an infinite changelevel was detected and will be disabled until a next save\\restore\n" ); + return; // lock with svs.spawncount here + } + } + SV_SkipUpdates (); - if( !s2 ) Cbuf_AddText( va( "changelevel %s\n", s1 )); // Quake changlevel - else Cbuf_AddText( va( "changelevel %s %s\n", s1, s2 )); // Half-Life changelevel + // changelevel will be executed on a next frame + if( smooth ) COM_ChangeLevel( mapname, landmark ); // Smoothed Half-Life changelevel + else COM_ChangeLevel( mapname, NULL ); // Classic Quake changlevel } /* @@ -2814,11 +2876,11 @@ static void pfnAlertMessage( ALERT_TYPE level, char *szFmt, ... ) if( level == at_warning ) { - Sys_Print( va( "^3Warning:^7 %s", buffer )); + Con_Printf( "^3Warning:^7 %s", buffer ); } else if( level == at_error ) { - Sys_Print( va( "^1Error:^7 %s", buffer )); + Con_Printf( "^1Error:^7 %s", buffer ); } else if( level == at_logged ) { @@ -2826,7 +2888,7 @@ static void pfnAlertMessage( ALERT_TYPE level, char *szFmt, ... ) } else { - Sys_Print( buffer ); + Con_Printf( buffer ); } } @@ -2994,7 +3056,7 @@ pfnPEntityOfEntOffset */ edict_t* pfnPEntityOfEntOffset( int iEntOffset ) { - return (&((edict_t*)svgame.vp)[iEntOffset]); + return (&((edict_t *)svgame.vp)[iEntOffset]); } /* @@ -3018,9 +3080,11 @@ int pfnIndexOfEdict( const edict_t *pEdict ) { int number; + if( !pEdict ) return 0; // world ? + number = NUM_FOR_EDICT( pEdict ); - if( number < 0 || number >= svgame.numEntities ) - return 0; // out of range + if( number < 0 || number > GI->max_edicts ) + Host_Error( "bad entity number %d\n", number ); return number; } @@ -3032,41 +3096,47 @@ pfnPEntityOfEntIndex */ edict_t* pfnPEntityOfEntIndex( int iEntIndex ) { - if( iEntIndex < 0 || iEntIndex >= svgame.numEntities ) - return NULL; // out of range + if( iEntIndex >= 0 && iEntIndex < GI->max_edicts ) + { + edict_t *pEdict = EDICT_NUM( iEntIndex ); - return EDICT_NUM( iEntIndex ); + if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE )) + return pEdict; // just get access to array + + if( SV_IsValidEdict( pEdict ) && pEdict->pvPrivateData ) + return pEdict; + + // g-cont: clients can be acessed even without private data! + if( SV_IsValidEdict( pEdict ) && SV_IsPlayerIndex( iEntIndex )) + return pEdict; + } + + return NULL; } /* ============= pfnFindEntityByVars -debug routine +debug thing ============= */ edict_t* pfnFindEntityByVars( entvars_t *pvars ) { - edict_t *e; + edict_t *pEdict; int i; // don't pass invalid arguments if( !pvars ) return NULL; - for( i = 0; i < svgame.numEntities; i++ ) + for( i = 0; i < GI->max_edicts; i++ ) { - e = EDICT_NUM( i ); - - if( &e->v == pvars ) - { - if( e->v.pContainingEntity != e ) - { - MsgDev( D_NOTE, "fixing pContainingEntity for %s\n", SV_ClassName( e )); - e->v.pContainingEntity = e; - } - return e; // found it - } + pEdict = EDICT_NUM( i ); + // g-cont: we should compare pointers + if( &pEdict->v == pvars ) + return pEdict; // found it } + return NULL; } @@ -3200,7 +3270,7 @@ pfnFunctionFromName */ dword pfnFunctionFromName( const char *pName ) { - return Com_FunctionFromName( svgame.hInstance, pName ); + return COM_FunctionFromName( svgame.hInstance, pName ); } /* @@ -3211,7 +3281,7 @@ pfnNameForFunction */ const char *pfnNameForFunction( dword function ) { - return Com_NameForFunction( svgame.hInstance, function ); + return COM_NameForFunction( svgame.hInstance, function ); } /* @@ -4765,7 +4835,6 @@ void SV_SpawnEntities( const char *mapname, char *entities ) svgame.movevars.fog_settings = 0; svgame.globals->maxEntities = GI->max_edicts; - svgame.globals->maxClients = svs.maxclients; svgame.globals->mapname = MAKE_STRING( sv.name ); svgame.globals->startspot = MAKE_STRING( sv.startspot ); svgame.globals->time = sv.time; @@ -4782,6 +4851,9 @@ void SV_SpawnEntities( const char *mapname, char *entities ) void SV_UnloadProgs( void ) { + if( !svgame.hInstance ) + return; + SV_DeactivateServer (); Delta_Shutdown (); Mod_ClearUserData (); @@ -4795,6 +4867,10 @@ void SV_UnloadProgs( void ) Cvar_FullSet( "host_gameloaded", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "sv_background", "0", FCVAR_READ_ONLY ); + // free entity baselines + Z_Free( svs.baselines ); + svs.baselines = NULL; + // remove server cmds SV_KillOperatorCommands(); @@ -4805,7 +4881,7 @@ void SV_UnloadProgs( void ) Mod_ResetStudioAPI (); - Com_FreeLibrary( svgame.hInstance ); + COM_FreeLibrary( svgame.hInstance ); Mem_FreePool( &svgame.mempool ); memset( &svgame, 0, sizeof( svgame )); } @@ -4828,7 +4904,7 @@ qboolean SV_LoadProgs( const char *name ) svgame.pmove = &gpMove; svgame.globals = &gpGlobals; svgame.mempool = Mem_AllocPool( "Server Edicts Zone" ); - svgame.hInstance = Com_LoadLibrary( name, true ); + svgame.hInstance = COM_LoadLibrary( name, true ); if( !svgame.hInstance ) return false; // make sure what new dll functions is cleared @@ -4840,23 +4916,23 @@ qboolean SV_LoadProgs( const char *name ) // make local copy of engfuncs to prevent overwrite it with bots.dll memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs )); - GetEntityAPI = (APIFUNCTION)Com_GetProcAddress( svgame.hInstance, "GetEntityAPI" ); - GetEntityAPI2 = (APIFUNCTION2)Com_GetProcAddress( svgame.hInstance, "GetEntityAPI2" ); - GiveNewDllFuncs = (NEW_DLL_FUNCTIONS_FN)Com_GetProcAddress( svgame.hInstance, "GetNewDLLFunctions" ); + GetEntityAPI = (APIFUNCTION)COM_GetProcAddress( svgame.hInstance, "GetEntityAPI" ); + GetEntityAPI2 = (APIFUNCTION2)COM_GetProcAddress( svgame.hInstance, "GetEntityAPI2" ); + GiveNewDllFuncs = (NEW_DLL_FUNCTIONS_FN)COM_GetProcAddress( svgame.hInstance, "GetNewDLLFunctions" ); if( !GetEntityAPI && !GetEntityAPI2 ) { - Com_FreeLibrary( svgame.hInstance ); + COM_FreeLibrary( svgame.hInstance ); MsgDev( D_NOTE, "SV_LoadProgs: failed to get address of GetEntityAPI proc\n" ); svgame.hInstance = NULL; return false; } - GiveFnptrsToDll = (GIVEFNPTRSTODLL)Com_GetProcAddress( svgame.hInstance, "GiveFnptrsToDll" ); + GiveFnptrsToDll = (GIVEFNPTRSTODLL)COM_GetProcAddress( svgame.hInstance, "GiveFnptrsToDll" ); if( !GiveFnptrsToDll ) { - Com_FreeLibrary( svgame.hInstance ); + COM_FreeLibrary( svgame.hInstance ); MsgDev( D_NOTE, "SV_LoadProgs: failed to get address of GiveFnptrsToDll proc\n" ); svgame.hInstance = NULL; return false; @@ -4888,7 +4964,7 @@ qboolean SV_LoadProgs( const char *name ) // fallback to old API if( !GetEntityAPI( &svgame.dllFuncs, version )) { - Com_FreeLibrary( svgame.hInstance ); + COM_FreeLibrary( svgame.hInstance ); MsgDev( D_ERROR, "SV_LoadProgs: couldn't get entity API\n" ); svgame.hInstance = NULL; return false; @@ -4898,7 +4974,7 @@ qboolean SV_LoadProgs( const char *name ) } else if( !GetEntityAPI( &svgame.dllFuncs, version )) { - Com_FreeLibrary( svgame.hInstance ); + COM_FreeLibrary( svgame.hInstance ); MsgDev( D_ERROR, "SV_LoadProgs: couldn't get entity API\n" ); svgame.hInstance = NULL; return false; @@ -4921,6 +4997,7 @@ qboolean SV_LoadProgs( const char *name ) svgame.globals->maxEntities = GI->max_edicts; svgame.globals->maxClients = svs.maxclients; svgame.edicts = Mem_Alloc( svgame.mempool, sizeof( edict_t ) * GI->max_edicts ); + svs.baselines = Z_Malloc( sizeof( entity_state_t ) * GI->max_edicts ); svgame.numEntities = svs.maxclients + 1; // clients + world for( i = 0, e = svgame.edicts; i < GI->max_edicts; i++, e++ ) diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 5a844468..926ef6f7 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -238,8 +238,8 @@ void SV_CreateGenericResources( void ) string filename, token; Q_strncpy( filename, sv.model_precache[1], sizeof( filename )); - FS_StripExtension( filename ); - FS_DefaultExtension( filename, ".res" ); + COM_StripExtension( filename ); + COM_DefaultExtension( filename, ".res" ); COM_FixSlashes( filename ); afile = FS_LoadFile( filename, NULL, false ); @@ -344,8 +344,8 @@ char *SV_EntityScript( void ) // check for entfile too Q_strncpy( entfilename, sv.worldmodel->name, sizeof( entfilename )); - FS_StripExtension( entfilename ); - FS_DefaultExtension( entfilename, ".ent" ); + COM_StripExtension( entfilename ); + COM_DefaultExtension( entfilename, ".ent" ); // make sure what entity patch is never than bsp ft1 = FS_FileTime( sv.worldmodel->name, false ); @@ -576,13 +576,8 @@ void SV_ActivateServer( int runPhysics ) // tell what kind of server has been started. if( svs.maxclients > 1 ) - { - MsgDev( D_INFO, "%i player server started\n", svs.maxclients ); - } - else - { - MsgDev( D_INFO, "Game started\n" ); - } + Con_Printf( "%i player server started\n", svs.maxclients ); + else Con_Printf( "Game started\n" ); Log_Printf( "Started map \"%s\" (CRC \"%i\")\n", sv.name, sv.worldmapCRC ); @@ -591,20 +586,18 @@ void SV_ActivateServer( int runPhysics ) Mod_FreeUnused (); host.movevars_changed = true; - Host_SetServerState( sv.state ); MsgDev( D_INFO, "level loaded at %.2f sec\n", Sys_DoubleTime() - svs.timestart ); if( svs.maxclients > 1 ) { - char *mapchangecfgfile = Cvar_VariableString( "mapchangecfgfile" ); - if( *mapchangecfgfile ) Cbuf_AddText( va( "exec %s\n", mapchangecfgfile )); + char *cycle = Cvar_VariableString( "mapchangecfgfile" ); + + if( COM_CheckString( cycle )) + Cbuf_AddText( va( "exec %s\n", cycle )); if( public_server->value ) - { - MsgDev( D_INFO, "Adding your server to master server list\n" ); Master_Add( ); - } } } @@ -666,8 +659,6 @@ qboolean SV_InitGame( void ) return false; // failed to loading server.dll } - // alloc baseline slots - svs.baselines = Z_Malloc( sizeof( entity_state_t ) * GI->max_edicts ); // client frames will be allocated in SV_ClientConnect svs.initialized = true; @@ -731,24 +722,13 @@ void SV_SetupClients( void ) // check if clients count was really changed if( svs.maxclients != (int)sv_maxclients->value ) changed_maxclients = true; + svs.maxclients = sv_maxclients->value; // copy the actual value from cvar - - if( svs.maxclients == 1 ) - { - if( deathmatch.value ) - { - changed_maxclients = true; - svs.maxclients = 8; - } - else if( coop.value ) - { - changed_maxclients = true; - svs.maxclients = 4; - } - } - if( !changed_maxclients ) return; // nothing to change + // if clients count was changed we need to run full shutdown procedure +// Host_ShutdownServer(); + // dedicated servers are can't be single player and are usually DM if( host.type == HOST_DEDICATED ) svs.maxclients = bound( 4, svs.maxclients, MAX_CLIENTS ); @@ -764,7 +744,6 @@ void SV_SetupClients( void ) // feedback for cvar Cvar_FullSet( "maxplayers", va( "%d", svs.maxclients ), FCVAR_LATCH ); SV_UPDATE_BACKUP = ( svs.maxclients == 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP; - svgame.globals->maxClients = svs.maxclients; svs.clients = Z_Realloc( svs.clients, sizeof( sv_client_t ) * svs.maxclients ); svs.num_client_entities = svs.maxclients * SV_UPDATE_BACKUP * NUM_PACKET_ENTITIES; @@ -773,15 +752,8 @@ void SV_SetupClients( void ) // init network stuff NET_Config(( svs.maxclients > 1 )); - - // copy gamemode into svgame.globals - svgame.globals->deathmatch = deathmatch.value; - svgame.globals->coop = coop.value; svgame.numEntities = svs.maxclients + 1; // clients + world - ClearBits( sv_maxclients->flags, FCVAR_CHANGED ); - ClearBits( deathmatch.flags, FCVAR_CHANGED ); - ClearBits( coop.flags, FCVAR_CHANGED ); } /* @@ -797,6 +769,9 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba int i, current_skill; edict_t *ent; + SV_SetupClients(); + SV_AllocClientFrames(); + if( !SV_InitGame( )) return false; @@ -804,9 +779,6 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba Log_Printf( "Loading map \"%s\"\n", mapname ); Log_PrintServerVars(); - SV_SetupClients(); - SV_AllocClientFrames(); - svs.timestart = Sys_DoubleTime(); svs.spawncount++; // any partially connected client will be restarted @@ -819,10 +791,7 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba MsgDev( D_INFO, "Spawn Server: %s\n", mapname ); } - sv.state = ss_dead; - Host_SetServerState( sv.state ); memset( &sv, 0, sizeof( sv )); // wipe the entire per-level structure - sv.time = svgame.globals->time = 1.0f; // server spawn time it's always 1.0 second sv.background = background; @@ -839,6 +808,11 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba current_skill = bound( 0, current_skill, 3 ); Cvar_SetValue( "skill", (float)current_skill ); + // copy gamemode into svgame.globals + svgame.globals->deathmatch = deathmatch.value; + svgame.globals->coop = coop.value; + svgame.globals->maxClients = svs.maxclients; + if( sv.background ) { // tell the game parts about background state @@ -851,8 +825,14 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY ); } + // force normal player collisions for single player + if( svs.maxclients == 1 ) Cvar_SetValue( "sv_clienttrace", 1 ); + // make sure what server name doesn't contain path and extension - FS_FileBase( mapname, sv.name ); + COM_FileBase( mapname, sv.name ); + + // precache and static commands can be issued during map initialization + sv.state = ss_loading; if( startspot ) Q_strncpy( sv.startspot, startspot, sizeof( sv.startspot )); @@ -863,6 +843,14 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba sv.worldmodel = sv.models[WORLD_INDEX] = Mod_LoadWorld( sv.model_precache[WORLD_INDEX], true ); CRC32_MapFile( &sv.worldmapCRC, sv.model_precache[WORLD_INDEX], svs.maxclients > 1 ); + if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ) && FS_FileExists( "progs.dat", false )) + { + file_t *f = FS_Open( "progs.dat", "rb", false ); + FS_Seek( f, sizeof( int ), SEEK_SET ); + FS_Read( f, &sv.progsCRC, sizeof( int )); + FS_Close( f ); + } + for( i = WORLD_INDEX; i < sv.worldmodel->numsubmodels; i++ ) { Q_sprintf( sv.model_precache[i+1], "*%i", i ); @@ -885,11 +873,6 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba // heartbeats will always be sent to the id master svs.last_heartbeat = MAX_HEARTBEAT; // send immediately - // precache and static commands can be issued during map initialization - sv.state = ss_loading; - - Host_SetServerState( sv.state ); - // get actual movevars SV_UpdateMovevars( true ); diff --git a/engine/server/sv_log.c b/engine/server/sv_log.c index cece81bf..45ef4c39 100644 --- a/engine/server/sv_log.c +++ b/engine/server/sv_log.c @@ -159,10 +159,10 @@ SV_ServerLog_f ==================== */ -void SV_ServerLog_f( sv_client_t *cl ) +qboolean SV_ServerLog_f( sv_client_t *cl ) { if( svs.maxclients <= 1 ) - return; + return false; if( Cmd_Argc() != 2 ) { @@ -171,7 +171,7 @@ void SV_ServerLog_f( sv_client_t *cl ) if( svs.log.active ) SV_ClientPrintf( cl, "currently logging\n" ); else SV_ClientPrintf( cl, "not currently logging\n" ); - return; + return true; } if( !Q_stricmp( Cmd_Argv( 1 ), "off" )) @@ -188,4 +188,6 @@ void SV_ServerLog_f( sv_client_t *cl ) { SV_ClientPrintf( cl, "log: unknown parameter %s\n", Cmd_Argv( 1 )); } + + return true; } \ No newline at end of file diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 67eb0872..2a60e1b6 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -59,8 +59,8 @@ CVAR_DEFINE_AUTO( mapcyclefile, "mapcycle.txt", 0, "name of multiplayer map cycl CVAR_DEFINE_AUTO( motdfile, "motd.txt", 0, "name of 'message of the day' file" ); CVAR_DEFINE_AUTO( logsdir, "logs", 0, "place to store multiplayer logs" ); CVAR_DEFINE_AUTO( bannedcfgfile, "banned.cfg", 0, "name of list of banned users" ); -CVAR_DEFINE_AUTO( deathmatch, "0", FCVAR_LATCH, "deathmatch mode in multiplayer game" ); -CVAR_DEFINE_AUTO( coop, "0", FCVAR_LATCH, "cooperative mode in multiplayer game" ); +CVAR_DEFINE_AUTO( deathmatch, "0", 0, "deathmatch mode in multiplayer game" ); +CVAR_DEFINE_AUTO( coop, "0", 0, "cooperative mode in multiplayer game" ); CVAR_DEFINE_AUTO( teamplay, "0", 0, "team mode in multiplayer game" ); CVAR_DEFINE_AUTO( skill, "1", 0, "skill level in singleplayer game" ); CVAR_DEFINE_AUTO( temp1, "0", 0, "temporary cvar that used by some mods" ); @@ -816,10 +816,10 @@ not just stuck on the outgoing message list, because the server is going to totally exit after returning from this function. ================== */ -void SV_FinalMessage( char *message, qboolean reconnect ) +void SV_FinalMessage( const char *message, qboolean reconnect ) { + byte msg_buf[64]; sv_client_t *cl; - byte msg_buf[1024]; sizebuf_t msg; int i; @@ -827,18 +827,8 @@ void SV_FinalMessage( char *message, qboolean reconnect ) MSG_BeginServerCmd( &msg, svc_print ); MSG_WriteString( &msg, va( "%s\n", message )); - if( reconnect ) - { - MSG_BeginServerCmd( &msg, svc_changing ); - - if( svs.maxclients > 1 || sv.changelevel ) - MSG_WriteOneBit( &msg, 1 ); // changelevel - else MSG_WriteOneBit( &msg, 0 ); - } - else - { - MSG_BeginServerCmd( &msg, svc_disconnect ); - } + if( reconnect ) SV_BuildReconnect( &msg ); + else MSG_BeginServerCmd( &msg, svc_disconnect ); // send it twice // stagger the packets to crutch operating system limited buffers @@ -882,7 +872,7 @@ Called when each game quits, before Sys_Quit or Sys_Error ================ */ -void SV_Shutdown( qboolean reconnect ) +void SV_Shutdown( const char *finalmsg ) { // already freed if( !SV_Initialized( )) return; @@ -890,32 +880,22 @@ void SV_Shutdown( qboolean reconnect ) // rcon will be disconnected SV_EndRedirect(); - if( host.type == HOST_DEDICATED ) - MsgDev( D_INFO, "SV_Shutdown: %s\n", host.finalmsg ); - if( svs.clients ) - SV_FinalMessage( host.finalmsg, reconnect ); + SV_FinalMessage( finalmsg, false ); if( public_server->value && svs.maxclients != 1 ) Master_Shutdown(); - if( !reconnect ) SV_UnloadProgs (); - else SV_DeactivateServer (); + NET_Config( false ); + SV_UnloadProgs (); // free current level memset( &sv, 0, sizeof( sv )); - Host_SetServerState( ss_dead ); SV_FreeClients(); Log_Printf( "Server shutdown\n" ); Log_Close(); - if( svs.baselines ) - { - Z_Free( svs.baselines ); - svs.baselines = NULL; - } - svs.initialized = false; } \ No newline at end of file diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 9d58e9de..87bf8c41 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -1815,6 +1815,9 @@ void SV_Physics( void ) // animate lightstyles (used for GetEntityIllum) SV_RunLightStyles (); + // increase framecount + sv.framecount++; + if( sv_skyspeed.value ) { // evaluate sky rotation. @@ -2057,7 +2060,7 @@ qboolean SV_InitPhysicsAPI( void ) { static PHYSICAPI pPhysIface; - pPhysIface = (PHYSICAPI)Com_GetProcAddress( svgame.hInstance, "Server_GetPhysicsInterface" ); + pPhysIface = (PHYSICAPI)COM_GetProcAddress( svgame.hInstance, "Server_GetPhysicsInterface" ); if( pPhysIface ) { if( pPhysIface( SV_PHYSICS_INTERFACE_VERSION, &gPhysicsAPI, &svgame.physFuncs )) diff --git a/engine/server/sv_save.c b/engine/server/sv_save.c index cdfadc97..521f89de 100644 --- a/engine/server/sv_save.c +++ b/engine/server/sv_save.c @@ -171,7 +171,7 @@ int SumBytes( SaveFileSectionsInfo_t *section ) void SV_InitSaveRestore( void ) { - pfnSaveGameComment = Com_GetProcAddress( svgame.hInstance, "SV_SaveGameComment" ); + pfnSaveGameComment = COM_GetProcAddress( svgame.hInstance, "SV_SaveGameComment" ); } /* @@ -713,7 +713,7 @@ void SV_DirectoryCopy( const char *pPath, file_t *pFile ) pCopy = FS_Open( t->filenames[i], "rb", true ); // filename can only be as long as a map name + extension - Q_strncpy( szName, FS_FileWithoutPath( t->filenames[i] ), SAVENAME_LENGTH ); + Q_strncpy( szName, COM_FileWithoutPath( t->filenames[i] ), SAVENAME_LENGTH ); FS_Write( pFile, szName, SAVENAME_LENGTH ); FS_Write( pFile, &fileSize, sizeof( int )); FS_FileCopy( pFile, pCopy, fileSize ); @@ -1960,6 +1960,7 @@ void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char pSaveData = SV_SaveGameState( true ); } + SV_InactivateClients (); SV_DeactivateServer (); if( !SV_SpawnServer( level, startspot, false )) @@ -1982,6 +1983,7 @@ void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char else { // classic quake changelevel + svgame.dllFuncs.pfnResetGlobalState(); SV_SpawnEntities( level, SV_EntityScript( )); SV_ActivateServer( true ); }