01 Mar 2018

This commit is contained in:
g-cont 2018-03-01 00:00:00 +03:00 committed by Alibek Omarov
parent 6441d5bfa2
commit 801b11117f
45 changed files with 981 additions and 1141 deletions

View File

@ -130,7 +130,7 @@ void CL_StartupDemoHeader( void )
return; 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 savepos;
long curpos; 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.demofile = FS_Open( name, "wb", false );
cls.demotime = 0.0; cls.demotime = 0.0;
@ -479,9 +479,7 @@ void CL_StopRecord( void )
demo.header.host_fps = 0.0; demo.header.host_fps = 0.0;
frames = cls.td_lastframe - cls.td_startframe; frames = cls.td_lastframe - cls.td_startframe;
Con_Printf( "Completed demo\nRecording time: %02d:%02d, frames %i\n", (int)(cls.demotime / 60.0f), (int)fmod(cls.demotime, 60.0f), frames );
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 );
cls.demotime = 0.0; cls.demotime = 0.0;
} }
@ -1094,7 +1092,7 @@ Called when a demo finishes
*/ */
qboolean CL_NextDemo( void ) qboolean CL_NextDemo( void )
{ {
string str; char str[MAX_QPATH];
if( cls.demonum == -1 ) if( cls.demonum == -1 )
return false; // don't play demos return false; // don't play demos
@ -1105,14 +1103,13 @@ qboolean CL_NextDemo( void )
cls.demonum = 0; cls.demonum = 0;
if( !cls.demos[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; cls.demonum = -1;
return false; return false;
} }
} }
Q_snprintf( str, MAX_STRING, "playdemo %s\n", cls.demos[cls.demonum] ); Q_snprintf( str, MAX_STRING, "playdemo %s\n", cls.demos[cls.demonum] );
Cbuf_InsertText( str ); Cbuf_InsertText( str );
cls.demonum++; cls.demonum++;
@ -1393,7 +1390,7 @@ void CL_StartDemos_f( void )
if( cls.key_dest != key_menu ) 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; return;
} }
@ -1404,7 +1401,7 @@ void CL_StartDemos_f( void )
c = MAX_DEMOS; 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++ ) for( i = 1; i < c + 1; i++ )
Q_strncpy( cls.demos[i-1], Cmd_Argv( i ), sizeof( cls.demos[0] )); 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 ) 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; return;
} }

View File

@ -333,9 +333,12 @@ print centerscreen message
*/ */
void CL_CenterPrint( const char *text, float y ) void CL_CenterPrint( const char *text, float y )
{ {
char *s;
int width = 0;
int length = 0; int length = 0;
int width = 0;
char *s;
if( !COM_CheckString( text ))
return;
clgame.centerPrint.lines = 1; clgame.centerPrint.lines = 1;
clgame.centerPrint.totalWidth = 0; clgame.centerPrint.totalWidth = 0;
@ -1437,7 +1440,7 @@ static client_sprite_t *pfnSPR_GetList( char *psz, int *piCount )
if( piCount ) *piCount = 0; if( piCount ) *piCount = 0;
if( !clgame.itemspath[0] ) // typically it's sprites\*.txt 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 ); afile = FS_LoadFile( psz, NULL, false );
if( !afile ) return NULL; if( !afile ) return NULL;
@ -1839,9 +1842,7 @@ prints directly into console (can skip notify)
*/ */
static void pfnConsolePrint( const char *string ) static void pfnConsolePrint( const char *string )
{ {
if( !string || !*string ) return; Con_Printf( "%s", string );
if( *string != 1 ) Con_Print( (char *)string ); // show notify
else Con_NPrintf( 0, (char *)string + 1 ); // skip notify
} }
/* /*
@ -1854,7 +1855,6 @@ like trigger_multiple message in q1
*/ */
static void pfnCenterPrint( const char *string ) static void pfnCenterPrint( const char *string )
{ {
if( !string || !*string ) return; // someone stupid joke
CL_CenterPrint( string, 0.25f ); CL_CenterPrint( string, 0.25f );
} }
@ -3707,7 +3707,7 @@ void CL_UnloadProgs( void )
Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
Cvar_FullSet( "host_clientloaded", "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( &cls.mempool );
Mem_FreePool( &clgame.mempool ); Mem_FreePool( &clgame.mempool );
memset( &clgame, 0, sizeof( clgame )); memset( &clgame, 0, sizeof( clgame ));
@ -3732,15 +3732,15 @@ qboolean CL_LoadProgs( const char *name )
clgame.mempool = Mem_AllocPool( "Client Edicts Zone" ); clgame.mempool = Mem_AllocPool( "Client Edicts Zone" );
clgame.entities = NULL; clgame.entities = NULL;
clgame.hInstance = Com_LoadLibrary( name, false ); clgame.hInstance = COM_LoadLibrary( name, false );
if( !clgame.hInstance ) return false; if( !clgame.hInstance ) return false;
// clear exports // clear exports
for( func = cdll_exports; func && func->name; func++ ) for( func = cdll_exports; func && func->name; func++ )
*func->func = NULL; *func->func = NULL;
// trying to get single export named 'F' // trying to get single export
if(( GetClientAPI = (void *)Com_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL ) if(( GetClientAPI = (void *)COM_GetProcAddress( clgame.hInstance, "GetClientAPI" )) != NULL )
{ {
MsgDev( D_NOTE, "CL_LoadProgs: found single callback export\n" ); 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' continue; // already get through 'F'
// functions are cleared before all the extensions are evaluated // 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 ); MsgDev( D_NOTE, "CL_LoadProgs: failed to get address of %s proc\n", func->name );
if( critical_exports ) if( critical_exports )
{ {
Com_FreeLibrary( clgame.hInstance ); COM_FreeLibrary( clgame.hInstance );
clgame.hInstance = NULL; clgame.hInstance = NULL;
return false; return false;
} }
@ -3793,13 +3793,13 @@ qboolean CL_LoadProgs( const char *name )
// functions are cleared before all the extensions are evaluated // functions are cleared before all the extensions are evaluated
// NOTE: new exports can be missed without stop the engine // NOTE: new exports can be missed without stop the engine
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 ); MsgDev( D_NOTE, "CL_LoadProgs: failed to get address of %s proc\n", func->name );
} }
if( !clgame.dllFuncs.pfnInitialize( &gEngfuncs, CLDLL_INTERFACE_VERSION )) 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" ); MsgDev( D_NOTE, "CL_LoadProgs: can't init client API\n" );
clgame.hInstance = NULL; clgame.hInstance = NULL;
return false; return false;

View File

@ -140,7 +140,7 @@ static void UI_DrawLogo( const char *filename, float x, float y, float width, fl
// run cinematic if not // run cinematic if not
Q_snprintf( path, sizeof( path ), "media/%s", filename ); Q_snprintf( path, sizeof( path ), "media/%s", filename );
FS_DefaultExtension( path, ".avi" ); COM_DefaultExtension( path, ".avi" );
fullpath = FS_GetDiskPath( path, false ); fullpath = FS_GetDiskPath( path, false );
if( FS_FileExists( path, false ) && !fullpath ) if( FS_FileExists( path, false ) && !fullpath )
@ -841,9 +841,9 @@ int pfnCheckGameDll( void )
if( SV_Initialized( )) return true; 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 true;
} }
return false; return false;
@ -988,7 +988,7 @@ void UI_UnloadProgs( void )
Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "host_gameuiloaded", "0", FCVAR_READ_ONLY );
Com_FreeLibrary( gameui.hInstance ); COM_FreeLibrary( gameui.hInstance );
Mem_FreePool( &gameui.mempool ); Mem_FreePool( &gameui.mempool );
memset( &gameui, 0, sizeof( gameui )); memset( &gameui, 0, sizeof( gameui ));
@ -1007,11 +1007,11 @@ qboolean UI_LoadProgs( void )
// setup globals // setup globals
gameui.globals = &gpGlobals; 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 ); FS_AllowDirectPaths( true );
if(!( gameui.hInstance = Com_LoadLibrary( "../menu.dll", false ))) if(!( gameui.hInstance = COM_LoadLibrary( "../menu.dll", false )))
{ {
FS_AllowDirectPaths( false ); FS_AllowDirectPaths( false );
return false; return false;
@ -1020,9 +1020,9 @@ qboolean UI_LoadProgs( void )
FS_AllowDirectPaths( false ); 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" ); MsgDev( D_NOTE, "UI_LoadProgs: can't init menu API\n" );
gameui.hInstance = NULL; gameui.hInstance = NULL;
return false; return false;
@ -1035,7 +1035,7 @@ qboolean UI_LoadProgs( void )
if( !GetMenuAPI( &gameui.dllFuncs, &gpEngfuncs, gameui.globals )) 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" ); MsgDev( D_NOTE, "UI_LoadProgs: can't init menu API\n" );
Mem_FreePool( &gameui.mempool ); Mem_FreePool( &gameui.mempool );
gameui.hInstance = NULL; gameui.hInstance = NULL;

View File

@ -195,13 +195,13 @@ void CL_SignonReply( void )
{ {
case 1: case 1:
// g-cont. my favorite message :-) // 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" ); CL_ServerCommand( true, "begin" );
if( host.developer >= D_REPORT ) if( host.developer >= D_REPORT )
Mem_PrintStats(); Mem_PrintStats();
break; break;
case 2: 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 ) if( cl.proxy_redirect && !cls.spectator )
CL_Disconnect(); CL_Disconnect();
cl.proxy_redirect = false; cl.proxy_redirect = false;
@ -311,13 +311,13 @@ void CL_ComputeClientInterpolationAmount( usercmd_t *cmd )
if(( interpolation_msec + 1 ) < min_interp ) 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; interpolation_msec = min_interp;
forced = true; forced = true;
} }
else if(( interpolation_msec - 1 ) > max_interp ) 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; interpolation_msec = max_interp;
forced = true; forced = true;
} }
@ -882,7 +882,7 @@ void CL_BeginUpload_f( void )
if( Q_strlen( name ) != 36 || Q_strnicmp( name, "!MD5", 4 )) 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; return;
} }
@ -1006,7 +1006,7 @@ void CL_SendConnectPacket( void )
if( !NET_StringToAdr( cls.servername, &adr )) 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; cls.connect_time = 0;
return; return;
} }
@ -1090,13 +1090,8 @@ void CL_Connect_f( void )
Q_strncpy( server, Cmd_Argv( 1 ), sizeof( server )); Q_strncpy( server, Cmd_Argv( 1 ), sizeof( server ));
if( Host_ServerState()) // if running a local server, kill it and reissue
{ if( SV_Active( )) Host_ShutdownServer();
// if running a local server, kill it and reissue
Q_strncpy( host.finalmsg, "Server quit", MAX_STRING );
SV_Shutdown( false );
}
NET_Config( true ); // allow remote NET_Config( true ); // allow remote
Msg( "server %s\n", server ); Msg( "server %s\n", server );
@ -1337,7 +1332,7 @@ void CL_LocalServers_f( void )
{ {
netadr_t adr; 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 NET_Config( true ); // allow remote
// send a broadcast packet // send a broadcast packet
@ -1357,11 +1352,11 @@ void CL_InternetServers_f( void )
netadr_t adr; netadr_t adr;
char fullquery[512] = "1\xFF" "0.0.0.0:0\0" "\\gamedir\\"; 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 NET_Config( true ); // allow remote
if( !NET_StringToAdr( MASTERSERVER_ADR, &adr ) ) 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 ); Q_strcpy( &fullquery[22], GI->gamedir );
@ -1537,7 +1532,7 @@ void CL_ParseStatusMessage( netadr_t from, sizebuf_t *msg )
CL_FixupColorStringsForInfoString( s, infostring ); CL_FixupColorStringsForInfoString( s, infostring );
// more info about servers // 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 ); UI_AddServerToList( from, infostring );
} }
@ -1790,7 +1785,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
{ {
if( cls.state == ca_connected ) if( cls.state == ca_connected )
{ {
MsgDev( D_INFO, "dup connect received. ignored\n"); MsgDev( D_ERROR, "dup connect received. ignored\n");
return; return;
} }
@ -1875,7 +1870,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
if( nr->timeout <= host.realtime ) if( nr->timeout <= host.realtime )
SetBits( nr->resp.error, NET_ERROR_TIMEOUT ); 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 ); nr->pfnFunc( &nr->resp );
// throw the list, now it will be stored in user area // 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 ) void CL_ProcessFile( qboolean successfully_received, const char *filename )
{ {
if( successfully_received ) 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 ); 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 ("drop", NULL, "drop current/specified item or weapon" );
Cmd_AddCommand ("gametitle", NULL, "show game logo" ); Cmd_AddCommand ("gametitle", NULL, "show game logo" );
Cmd_AddCommand ("god", NULL, "enable godmode" ); Cmd_AddCommand ("god", NULL, "enable godmode" );
Cmd_AddCommand ("fly", NULL, "enable fly mode" );
Cmd_AddCommand ("fov", NULL, "set client field of view" ); Cmd_AddCommand ("fov", NULL, "set client field of view" );
Cmd_AddCommand ("log", NULL, "logging server events" ); Cmd_AddCommand ("log", NULL, "logging server events" );
@ -2612,7 +2606,7 @@ void CL_Shutdown( void )
if( !cls.initialized ) return; if( !cls.initialized ) return;
cls.initialized = false; cls.initialized = false;
MsgDev( D_INFO, "CL_Shutdown()\n" ); Con_Printf( "CL_Shutdown()\n" );
Host_WriteOpenGLConfig (); Host_WriteOpenGLConfig ();
Host_WriteVideoConfig (); Host_WriteVideoConfig ();

View File

@ -33,7 +33,7 @@ const char *svc_strings[svc_lastmsg+1] =
"svc_nop", "svc_nop",
"svc_disconnect", "svc_disconnect",
"svc_event", "svc_event",
"svc_changing", "svc_version",
"svc_setview", "svc_setview",
"svc_sound", "svc_sound",
"svc_time", "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_Write( fp, MSG_GetData( msg ), MSG_GetMaxBytes( msg ));
FS_Close( fp ); 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 ) void CL_WriteMessageHistory( void )
{ {
int i, thecmd;
oldcmd_t *old, *failcommand; oldcmd_t *old, *failcommand;
sizebuf_t *msg = &net_message; sizebuf_t *msg = &net_message;
int i, thecmd;
if( !cls.initialized || cls.state == ca_disconnected ) if( !cls.initialized || cls.state == ca_disconnected )
return; return;
@ -195,7 +195,7 @@ void CL_WriteMessageHistory( void )
if( !cls_message_debug.parsing ) if( !cls_message_debug.parsing )
return; return;
MsgDev( D_INFO, "Last %i messages parsed.\n", MSG_COUNT ); Con_Printf( "Last %i messages parsed.\n", MSG_COUNT );
// finish here // finish here
thecmd = cls_message_debug.currentcmd - 1; thecmd = cls_message_debug.currentcmd - 1;
@ -205,19 +205,14 @@ void CL_WriteMessageHistory( void )
{ {
thecmd &= MSG_MASK; thecmd &= MSG_MASK;
old = &cls_message_debug.oldcmd[thecmd]; old = &cls_message_debug.oldcmd[thecmd];
Con_Printf( "%i %04i %s\n", old->frame_number, old->starting_offset, CL_MsgInfo( old->command ));
MsgDev( D_INFO,"%i %04i %s\n", old->frame_number, old->starting_offset, CL_MsgInfo( old->command ));
thecmd++; thecmd++;
} }
failcommand = &cls_message_debug.oldcmd[thecmd]; failcommand = &cls_message_debug.oldcmd[thecmd];
MsgDev( D_INFO, "BAD: %3i:%s\n", MSG_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command )); Con_Printf( "BAD: %3i:%s\n", MSG_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command ));
if( host.developer >= 2 )
if( host.developer >= 3 )
{
CL_WriteErrorMessage( MSG_GetNumBytesRead( msg ) - 1, msg ); CL_WriteErrorMessage( MSG_GetNumBytesRead( msg ) - 1, msg );
}
cls_message_debug.parsing = false; cls_message_debug.parsing = false;
} }
@ -743,6 +738,7 @@ void CL_ParseServerData( sizebuf_t *msg )
qboolean background; qboolean background;
MsgDev( D_NOTE, "Serverdata packet received.\n" ); MsgDev( D_NOTE, "Serverdata packet received.\n" );
cls.timestart = Sys_DoubleTime();
cls.demowaiting = false; // server is changed cls.demowaiting = false; // server is changed
cls.state = ca_connected; cls.state = ca_connected;
@ -1204,7 +1200,7 @@ void CL_ParseRestore( sizebuf_t *msg )
for( i = 0; i < mapCount; i++ ) for( i = 0; i < mapCount; i++ )
{ {
pMapName = MSG_ReadString( msg ); 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 ) if( cls.state != ca_disconnected )
{ {
MsgDev( D_INFO, "Setting up renderer...\n" ); Con_Printf( "Setting up renderer...\n" );
// load tempent sprites (glowshell, muzzleflashes etc) // load tempent sprites (glowshell, muzzleflashes etc)
CL_LoadClientSprites (); CL_LoadClientSprites ();
@ -2277,30 +2273,10 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
CL_ParseEvent( msg ); CL_ParseEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart; cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break; break;
case svc_changing: case svc_version:
if( MSG_ReadOneBit( msg )) param1 = MSG_ReadLong( msg );
{ if( param1 != PROTOCOL_VERSION )
cls.changelevel = true; Host_Error( "Server is protocol %i instead of %i\n", param1, PROTOCOL_VERSION );
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
break; break;
case svc_setview: case svc_setview:
CL_ParseViewEntity( msg ); CL_ParseViewEntity( msg );
@ -2313,7 +2289,9 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
CL_ParseServerTime( msg ); CL_ParseServerTime( msg );
break; break;
case svc_print: 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; break;
case svc_stufftext: case svc_stufftext:
Cbuf_AddText( MSG_ReadString( msg )); Cbuf_AddText( MSG_ReadString( msg ));

View File

@ -154,8 +154,8 @@ void CL_UpdateTexture( mstudiotexture_t *ptexture, int topcolor, int bottomcolor
// build name of original texture // build name of original texture
Q_strncpy( mdlname, RI.currentmodel->name, sizeof( mdlname )); Q_strncpy( mdlname, RI.currentmodel->name, sizeof( mdlname ));
FS_FileBase( ptexture->name, name ); COM_FileBase( ptexture->name, name );
FS_StripExtension( mdlname ); COM_StripExtension( mdlname );
Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name ); Q_snprintf( texname, sizeof( texname ), "#%s/%s.mdl", mdlname, name );
index = GL_FindTexture( texname ); index = GL_FindTexture( texname );

View File

@ -596,8 +596,8 @@ qboolean VID_CubemapShot( const char *base, uint size, const float *vieworg, qbo
// make sure what we have right extension // make sure what we have right extension
Q_strncpy( basename, base, MAX_STRING ); Q_strncpy( basename, base, MAX_STRING );
FS_StripExtension( basename ); COM_StripExtension( basename );
FS_DefaultExtension( basename, ".tga" ); COM_DefaultExtension( basename, ".tga" );
// write image as 6 sides // write image as 6 sides
result = FS_SaveImage( basename, r_shot ); result = FS_SaveImage( basename, r_shot );
@ -706,7 +706,7 @@ rebuild_page:
if( FBitSet( image->flags, TF_DEPTHMAP ) && !FBitSet( image->flags, TF_NOCOMPARE )) 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 ); 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 ) if( Q_strlen( shortname ) > 18 )
{ {
// cutoff too long names, it looks ugly // cutoff too long names, it looks ugly

View File

@ -1169,7 +1169,7 @@ int R_CreateDecalList( decallist_t *pList )
pList[total].scale = decal->scale; pList[total].scale = decal->scale;
R_DecalUnProject( decal, &pList[total] ); 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 // check to see if the decal should be added
total = DecalListAdd( pList, total ); total = DecalListAdd( pList, total );

View File

@ -1310,7 +1310,7 @@ int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags, i
} }
// see if already loaded // 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 ) 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 FS_FreeImage( pic ); // release source texture
// add to hash table // 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]; tex->nextHash = r_texturesHashTable[hash];
r_texturesHashTable[hash] = tex; r_texturesHashTable[hash] = tex;
@ -1406,7 +1406,7 @@ int GL_LoadTextureArray( const char **names, int flags, imgfilter_t *filter )
// create complexname from layer names // create complexname from layer names
for( i = 0; i < numLayers; i++ ) for( i = 0; i < numLayers; i++ )
{ {
FS_FileBase( names[i], basename ); COM_FileBase( names[i], basename );
Q_strncat( name, va( "%s", basename ), sizeof( name )); Q_strncat( name, va( "%s", basename ), sizeof( name ));
if( i != ( numLayers - 1 )) Q_strncat( name, "|", 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 // 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 ) 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 FS_FreeImage( pic ); // release source texture
// add to hash table // 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]; tex->nextHash = r_texturesHashTable[hash];
r_texturesHashTable[hash] = tex; r_texturesHashTable[hash] = tex;
@ -1569,7 +1569,7 @@ int GL_LoadTextureInternal( const char *name, rgbdata_t *pic, texFlags_t flags,
} }
// see if already loaded // 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 ) 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]; 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 )); Q_strncpy( tex->name, name, sizeof( tex->name ));
tex->texnum = i; // texnum is used for fast acess into r_textures array too tex->texnum = i; // texnum is used for fast acess into r_textures array too
tex->flags = flags; tex->flags = flags;
@ -1626,7 +1626,7 @@ int GL_LoadTextureInternal( const char *name, rgbdata_t *pic, texFlags_t flags,
if( !update ) if( !update )
{ {
// add to hash table // 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]; tex->nextHash = r_texturesHashTable[hash];
r_texturesHashTable[hash] = tex; r_texturesHashTable[hash] = tex;
} }
@ -1789,7 +1789,7 @@ int GL_FindTexture( const char *name )
} }
// see if already loaded // 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 ) for( tex = r_texturesHashTable[hash]; tex != NULL; tex = tex->nextHash )
{ {
@ -1822,7 +1822,7 @@ void GL_FreeImage( const char *name )
} }
// see if already loaded // 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 ) for( tex = r_texturesHashTable[hash]; tex != NULL; tex = tex->nextHash )
{ {
@ -1870,7 +1870,7 @@ void R_FreeImage( gltexture_t *image )
} }
// remove from hash table // remove from hash table
hash = Com_HashKey( image->name, TEXTURES_HASH_SIZE ); hash = COM_HashKey( image->name, TEXTURES_HASH_SIZE );
prev = &r_texturesHashTable[hash]; prev = &r_texturesHashTable[hash];
while( 1 ) while( 1 )
@ -2729,7 +2729,7 @@ void R_InitImages( void )
// create unused 0-entry // create unused 0-entry
Q_strncpy( r_textures->name, "*unused*", sizeof( r_textures->name )); 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_textures->nextHash = r_texturesHashTable[hash];
r_texturesHashTable[hash] = r_textures; r_texturesHashTable[hash] = r_textures;
r_numTextures = 1; r_numTextures = 1;

View File

@ -455,7 +455,7 @@ void R_NewMap( void )
string mapname, filepath; string mapname, filepath;
Q_strncpy( mapname, cl.worldmodel->name, sizeof( mapname )); Q_strncpy( mapname, cl.worldmodel->name, sizeof( mapname ));
FS_StripExtension( mapname ); COM_StripExtension( mapname );
Q_sprintf( filepath, "%s_detail.txt", mapname ); Q_sprintf( filepath, "%s_detail.txt", mapname );
R_ParseDetailTextures( filepath ); R_ParseDetailTextures( filepath );

View File

@ -147,24 +147,6 @@ void R_StudioInit( void )
m_fDoRemap = false; 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 R_GetEntityRenderMode
@ -194,32 +176,6 @@ int R_GetEntityRenderMode( cl_entity_t *ent )
return ent->curstate.rendermode; 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 R_StudioSetupTimings
@ -821,8 +777,8 @@ void *R_StudioGetAnim( studiohdr_t *m_pStudioHeader, model_t *m_pSubModel, mstud
{ {
string filepath, modelname, modelpath; string filepath, modelname, modelpath;
FS_FileBase( m_pSubModel->name, modelname ); COM_FileBase( m_pSubModel->name, modelname );
FS_ExtractFilePath( m_pSubModel->name, modelpath ); COM_ExtractFilePath( m_pSubModel->name, modelpath );
// NOTE: here we build real sub-animation filename because stupid user may rename model without recompile // 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 ); 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 )); Q_strncpy( mdlname, mod->name, sizeof( mdlname ));
FS_FileBase( ptexture->name, name ); COM_FileBase( ptexture->name, name );
FS_StripExtension( mdlname ); COM_StripExtension( mdlname );
// loading texture filter for studiomodel // loading texture filter for studiomodel
if( !FBitSet( ptexture->flags, STUDIO_NF_COLORMAP )) 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 ) if( !ptexture->index )
{ {
MsgDev( D_WARN, "%s has null texture %s\n", mod->name, ptexture->name );
ptexture->index = tr.defaultTexture; ptexture->index = tr.defaultTexture;
} }
else else if( tx )
{ {
// duplicate texnum for easy acess // 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; mstudiotexture_t *ptexture;
int i; int i;
if( host.type == HOST_DEDICATED ) if( !phdr || host.type == HOST_DEDICATED )
return; return;
ptexture = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex); 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 = (studiohdr_t *)data;
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;
mstudiotexture_t *ptexture; mstudiotexture_t *ptexture;
int i; int i;
Assert( mod != NULL ); if( !phdr || host.type == HOST_DEDICATED )
return;
if( mod->type != mod_studio ) ptexture = (mstudiotexture_t *)(((byte *)phdr) + phdr->textureindex);
return; // not a studio
pstudio = mod->cache.data;
if( !pstudio ) return; // already freed
ptexture = (mstudiotexture_t *)(((byte *)pstudio) + pstudio->textureindex);
// release all textures // release all textures
for( i = 0; i < pstudio->numtextures; i++ ) for( i = 0; i < phdr->numtextures; i++ )
{ {
if( ptexture[i].index == tr.defaultTexture ) if( ptexture[i].index == tr.defaultTexture )
continue; continue;
GL_FreeTexture( ptexture[i].index ); GL_FreeTexture( ptexture[i].index );
} }
Mem_FreePool( &mod->mempool );
memset( mod, 0, sizeof( *mod ));
} }
static engine_studio_api_t gStudioAPI = static engine_studio_api_t gStudioAPI =

View File

@ -449,7 +449,7 @@ void R_SetupSky( const char *skyboxname )
} }
Q_snprintf( loadname, sizeof( loadname ), "gfx/env/%s", 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 // kill the underline suffix to find them manually later
if( loadname[Q_strlen( loadname ) - 1] == '_' ) 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 // to prevent infinite recursion if default skybox was missed
if( result == SKYBOX_MISSED && Q_stricmp( loadname, "gfx/env/desert" )) 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 R_SetupSky( "desert" ); // force to default
return; return;
} }
// release old skybox // release old skybox
R_UnloadSkybox(); 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] ); Q_snprintf( sidename, sizeof( sidename ), "%s%s", loadname, r_skyBoxSuffix[i] );
tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY, NULL ); else Q_snprintf( sidename, sizeof( sidename ), "%s_%s", loadname, r_skyBoxSuffix[i] );
if( !tr.skyboxTextures[i] ) break;
} tr.skyboxTextures[i] = GL_LoadTexture( sidename, NULL, 0, TF_CLAMP|TF_SKY, NULL );
} if( !tr.skyboxTextures[i] ) break;
else if( result == SKYBOX_Q1STYLE ) Con_DPrintf( "%s%s, ", skyboxname, r_skyBoxSuffix[i] );
{
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;
}
} }
if( i == 6 ) if( i == 6 )
{ {
SetBits( world.flags, FWORLD_CUSTOM_SKYBOX ); SetBits( world.flags, FWORLD_CUSTOM_SKYBOX );
Con_DPrintf( "done\n" );
return; // loaded 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(); R_UnloadSkybox();
} }

View File

@ -179,7 +179,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
COM_FixSlashes( name ); COM_FixSlashes( name );
// see if already loaded // 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 ) for( sfx = s_sfxHashList[hash]; sfx; sfx = sfx->hashNext )
{ {
if( !Q_strcmp( sfx->name, name )) if( !Q_strcmp( sfx->name, name ))
@ -214,7 +214,7 @@ sfx_t *S_FindName( const char *pname, int *pfInCache )
if( pfInCache ) *pfInCache = false; if( pfInCache ) *pfInCache = false;
Q_strncpy( sfx->name, name, MAX_STRING ); Q_strncpy( sfx->name, name, MAX_STRING );
sfx->touchFrame = s_registration_sequence; 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 // link it in
sfx->hashNext = s_sfxHashList[sfx->hashValue]; sfx->hashNext = s_sfxHashList[sfx->hashValue];

View File

@ -625,7 +625,7 @@ movie_state_t *AVI_LoadVideo( const char *filename, qboolean load_audio )
// open cinematic // open cinematic
Q_snprintf( path, sizeof( path ), "media/%s", filename ); Q_snprintf( path, sizeof( path ), "media/%s", filename );
FS_DefaultExtension( path, ".avi" ); COM_DefaultExtension( path, ".avi" );
fullpath = FS_GetDiskPath( path, false ); fullpath = FS_GetDiskPath( path, false );
if( FS_FileExists( path, false ) && !fullpath ) if( FS_FileExists( path, false ) && !fullpath )

View File

@ -328,8 +328,8 @@ void Cmd_Echo_f( void )
int i; int i;
for( i = 1; i < Cmd_Argc(); i++ ) for( i = 1; i < Cmd_Argc(); i++ )
Sys_Print( Cmd_Argv( i )); Con_Printf( Cmd_Argv( i ));
Sys_Print( "\n" ); Con_Printf( "\n" );
} }
/* /*

View File

@ -147,6 +147,163 @@ long COM_RandomLong( long lLow, long lHigh )
return lLow + (n % x); 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 COM_IsSingleChar
@ -762,54 +919,6 @@ void pfnCVarDirectSet( cvar_t *var, const char *szValue )
Cvar_DirectSet( (convar_t *)var, 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 COM_CompareFileTime
@ -913,7 +1022,7 @@ qboolean COM_IsSafeFileToDownload( const char *filename )
if( Q_strlen( first ) != 4 ) if( Q_strlen( first ) != 4 )
return false; return false;
ext = FS_FileExtension( lwrfilename ); ext = COM_FileExtension( lwrfilename );
for( i = 0; i < ARRAYSIZE( file_exts ); i++ ) for( i = 0; i < ARRAYSIZE( file_exts ); i++ )
{ {

View File

@ -402,12 +402,12 @@ void FS_AllowDirectPaths( qboolean enable );
void FS_AddGameDirectory( const char *dir, int flags ); void FS_AddGameDirectory( const char *dir, int flags );
void FS_AddGameHierarchy( const char *dir, int flags ); void FS_AddGameHierarchy( const char *dir, int flags );
void FS_LoadGameInfo( const char *rootfolder ); void FS_LoadGameInfo( const char *rootfolder );
void FS_FileBase( const char *in, char *out ); void COM_FileBase( const char *in, char *out );
const char *FS_FileExtension( const char *in ); const char *COM_FileExtension( const char *in );
void FS_DefaultExtension( char *path, const char *extension ); void COM_DefaultExtension( char *path, const char *extension );
void FS_ExtractFilePath( const char *path, char *dest ); void COM_ExtractFilePath( const char *path, char *dest );
const char *FS_GetDiskPath( const char *name, qboolean gamedironly ); 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 ); byte *W_LoadLump( wfile_t *wad, const char *lumpname, size_t *lumpsizeptr, const char type );
void W_Close( wfile_t *wad ); void W_Close( wfile_t *wad );
byte *FS_LoadFile( const char *path, long *filesizeptr, qboolean gamedironly ); 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_FileCopy( file_t *pOutput, file_t *pInput, int fileSize );
qboolean FS_Delete( const char *path ); qboolean FS_Delete( const char *path );
int FS_UnGetc( file_t *file, byte c ); int FS_UnGetc( file_t *file, byte c );
void FS_StripExtension( char *path ); void COM_StripExtension( char *path );
long FS_Tell( file_t *file ); long FS_Tell( file_t *file );
qboolean FS_Eof( file_t *file ); qboolean FS_Eof( file_t *file );
int FS_Close( file_t *file ); int FS_Close( file_t *file );
@ -662,8 +662,6 @@ int Q_buildnum( void );
// host.c // host.c
// //
void EXPORT Host_Shutdown( void ); void EXPORT Host_Shutdown( void );
void Host_SetServerState( int state );
int Host_ServerState( void );
int Host_CompareFileTime( long ft1, long ft2 ); int Host_CompareFileTime( long ft1, long ft2 );
void Host_NewInstance( const char *name, const char *finalmsg ); void Host_NewInstance( const char *name, const char *finalmsg );
void Host_EndGame( qboolean abort, const char *message, ... ); void Host_EndGame( qboolean abort, const char *message, ... );
@ -708,7 +706,7 @@ void Host_ClientFrame( void );
qboolean CL_Active( void ); qboolean CL_Active( void );
void SV_Init( void ); void SV_Init( void );
void SV_Shutdown( qboolean reconnect ); void SV_Shutdown( const char *finalmsg );
void Host_ServerFrame( void ); void Host_ServerFrame( void );
qboolean SV_Active( 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 MD5Update( MD5Context_t *ctx, const byte *buf, uint len );
void MD5Final( byte digest[16], MD5Context_t *ctx ); void MD5Final( byte digest[16], MD5Context_t *ctx );
qboolean MD5_HashFile( byte digest[16], const char *pszFileName, uint seed[4] ); 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] ); char *MD5_Print( byte hash[16] );
// //

View File

@ -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 ); t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps->value );
if( !t ) return false; if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf ); COM_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true; 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++ ) for( i = 0, nummaps = 0; i < t->numfilenames; i++ )
{ {
char entfilename[MAX_QPATH]; 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; int ver = -1, lumpofs = 0, lumplen = 0;
char *ents = NULL, *pfile; char *ents = NULL, *pfile;
qboolean validmap = false; qboolean validmap = false;
@ -91,8 +91,8 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
if( hdrext->id == IDEXTRAHEADER ) version = hdrext->version; if( hdrext->id == IDEXTRAHEADER ) version = hdrext->version;
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename )); Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
FS_StripExtension( entfilename ); COM_StripExtension( entfilename );
FS_DefaultExtension( entfilename, ".ent" ); COM_DefaultExtension( entfilename, ".ent" );
ents = FS_LoadFile( entfilename, NULL, true ); ents = FS_LoadFile( entfilename, NULL, true );
if( !ents && lumplen >= 10 ) if( !ents && lumplen >= 10 )
@ -126,7 +126,7 @@ qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
} }
if( f ) FS_Close(f); if( f ) FS_Close(f);
FS_FileBase( t->filenames[i], matchbuf ); COM_FileBase( t->filenames[i], matchbuf );
switch( ver ) 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 t = FS_Search( va( "demos/%s*.dem", s ), true, true ); // lookup only in gamedir
if( !t ) return false; if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf ); COM_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true; if( t->numfilenames == 1 ) return true;
for( i = 0, numdems = 0; i < t->numfilenames; i++ ) 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; continue;
FS_FileBase( t->filenames[i], matchbuf ); COM_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf ); Msg( "%16s\n", matchbuf );
numdems++; 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 ); t = FS_Search( va( "media/%s*.avi", s ), true, false );
if( !t ) return false; if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf ); COM_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true; if( t->numfilenames == 1 ) return true;
for(i = 0, nummovies = 0; i < t->numfilenames; i++) 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; continue;
FS_FileBase( t->filenames[i], matchbuf ); COM_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf ); Msg( "%16s\n", matchbuf );
nummovies++; nummovies++;
} }
@ -273,19 +273,19 @@ qboolean Cmd_GetMusicList( const char *s, char *completedname, int length )
t = FS_Search( va( "media/%s*.*", s ), true, false ); t = FS_Search( va( "media/%s*.*", s ), true, false );
if( !t ) return false; if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf ); COM_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true; if( t->numfilenames == 1 ) return true;
for(i = 0, numtracks = 0; i < t->numfilenames; i++) 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" )) if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" ))
continue; continue;
FS_FileBase( t->filenames[i], matchbuf ); COM_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf ); Msg( "%16s\n", matchbuf );
numtracks++; 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 t = FS_Search( va( "save/%s*.sav", s ), true, true ); // lookup only in gamedir
if( !t ) return false; if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf ); COM_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true; if( t->numfilenames == 1 ) return true;
for( i = 0, numsaves = 0; i < t->numfilenames; i++ ) 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; continue;
FS_FileBase( t->filenames[i], matchbuf ); COM_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf ); Msg( "%16s\n", matchbuf );
numsaves++; numsaves++;
} }
@ -368,17 +368,17 @@ qboolean Cmd_GetConfigList( const char *s, char *completedname, int length )
t = FS_Search( va( "%s*.cfg", s ), true, false ); t = FS_Search( va( "%s*.cfg", s ), true, false );
if( !t ) return false; if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf ); COM_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true; if( t->numfilenames == 1 ) return true;
for( i = 0, numconfigs = 0; i < t->numfilenames; i++ ) 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; continue;
FS_FileBase( t->filenames[i], matchbuf ); COM_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf ); Msg( "%16s\n", matchbuf );
numconfigs++; numconfigs++;
} }
@ -417,20 +417,20 @@ qboolean Cmd_GetSoundList( const char *s, char *completedname, int length )
if( !t ) return false; if( !t ) return false;
Q_strncpy( matchbuf, t->filenames[0] + Q_strlen( snddir ), MAX_STRING ); Q_strncpy( matchbuf, t->filenames[0] + Q_strlen( snddir ), MAX_STRING );
FS_StripExtension( matchbuf ); COM_StripExtension( matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true; if( t->numfilenames == 1 ) return true;
for(i = 0, numsounds = 0; i < t->numfilenames; i++) 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" )) if( Q_stricmp( ext, "wav" ) && Q_stricmp( ext, "mp3" ))
continue; continue;
Q_strncpy( matchbuf, t->filenames[i] + Q_strlen(snddir), MAX_STRING ); Q_strncpy( matchbuf, t->filenames[i] + Q_strlen(snddir), MAX_STRING );
FS_StripExtension( matchbuf ); COM_StripExtension( matchbuf );
Msg( "%16s\n", matchbuf ); Msg( "%16s\n", matchbuf );
numsounds++; 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 ); t = FS_Search( va( "%s/%s*.txt", clgame.itemspath, s ), true, false );
if( !t ) return false; if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf ); COM_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true; if( t->numfilenames == 1 ) return true;
for(i = 0, numitems = 0; i < t->numfilenames; i++) 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; continue;
FS_FileBase( t->filenames[i], matchbuf ); COM_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf ); Msg( "%16s\n", matchbuf );
numitems++; numitems++;
} }
@ -514,17 +514,17 @@ qboolean Cmd_GetCustomList( const char *s, char *completedname, int length )
t = FS_Search( va( "%s*.hpk", s ), true, false ); t = FS_Search( va( "%s*.hpk", s ), true, false );
if( !t ) return false; if( !t ) return false;
FS_FileBase( t->filenames[0], matchbuf ); COM_FileBase( t->filenames[0], matchbuf );
if( completedname && length ) if( completedname && length )
Q_strncpy( completedname, matchbuf, length ); Q_strncpy( completedname, matchbuf, length );
if( t->numfilenames == 1 ) return true; if( t->numfilenames == 1 ) return true;
for(i = 0, numitems = 0; i < t->numfilenames; i++) 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; continue;
FS_FileBase( t->filenames[i], matchbuf ); COM_FileBase( t->filenames[i], matchbuf );
Msg( "%16s\n", matchbuf ); Msg( "%16s\n", matchbuf );
numitems++; numitems++;
} }
@ -687,11 +687,11 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
int lumpofs = 0, lumplen = 0; int lumpofs = 0, lumplen = 0;
string mapname, message, entfilename; string mapname, message, entfilename;
if( Q_stricmp( FS_FileExtension( t->filenames[i] ), "bsp" )) if( Q_stricmp( COM_FileExtension( t->filenames[i] ), "bsp" ))
continue; continue;
f = FS_Open( t->filenames[i], "rb", onlyingamedir ); f = FS_Open( t->filenames[i], "rb", onlyingamedir );
FS_FileBase( t->filenames[i], mapname ); COM_FileBase( t->filenames[i], mapname );
if( f ) if( f )
{ {
@ -714,8 +714,8 @@ qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
lumplen = header->lumps[LUMP_ENTITIES].filelen; lumplen = header->lumps[LUMP_ENTITIES].filelen;
Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename )); Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
FS_StripExtension( entfilename ); COM_StripExtension( entfilename );
FS_DefaultExtension( entfilename, ".ent" ); COM_DefaultExtension( entfilename, ".ent" );
ents = FS_LoadFile( entfilename, NULL, true ); ents = FS_LoadFile( entfilename, NULL, true );
if( !ents && lumplen >= 10 ) if( !ents && lumplen >= 10 )

View File

@ -434,7 +434,8 @@ void Con_AddLine( const char *line, int length )
byte *putpos; byte *putpos;
con_lineinfo_t *p; con_lineinfo_t *p;
if( !con.initialized ) return; if( !con.initialized || !con.buffer )
return;
Con_FixTimes(); Con_FixTimes();
length++; // reserve space for term length++; // reserve space for term
@ -1011,7 +1012,7 @@ void Con_Print( const char *txt )
int c, mask; int c, mask;
// client not running // client not running
if( !con.initialized || !con.buffer || host.type == HOST_DEDICATED ) if( !con.initialized || !con.buffer )
return; return;
if( txt[0] == 2 ) 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 Con_NPrint
@ -1914,6 +1963,9 @@ int Con_DrawConsoleLine( int y, int lineno )
{ {
con_lineinfo_t *li = &CON_LINES( 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 ) if( y >= con.curFont->charHeight )
Con_DrawGenericString( con.curFont->charWidths[' '], y, li->start, g_color_table[7], false, -1 ); Con_DrawGenericString( con.curFont->charWidths[' '], y, li->start, g_color_table[7], false, -1 );

View File

@ -203,9 +203,9 @@ byte CRC32_BlockSequence( byte *base, int length, int sequence )
qboolean CRC32_File( dword *crcvalue, const char *filename ) qboolean CRC32_File( dword *crcvalue, const char *filename )
{ {
file_t *f;
char buffer[1024]; char buffer[1024];
int num_bytes; int num_bytes;
file_t *f;
f = FS_Open( filename, "rb", false ); f = FS_Open( filename, "rb", false );
if( !f ) return false; if( !f ) return false;
@ -588,12 +588,12 @@ char *MD5_Print( byte hash[16] )
/* /*
================= =================
Com_HashKey COM_HashKey
returns hash key for string 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; uint i, hashKey = 0;

View File

@ -112,7 +112,6 @@ qboolean fs_ext_path = false; // attempt to read\write from ./ or ../ pathes
static const wadtype_t wad_hints[10]; static const wadtype_t wad_hints[10];
static void FS_InitMemory( void ); 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 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 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 ); 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_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 FS_LoadPackPAK
@ -536,7 +493,7 @@ static qboolean FS_AddWad_Fullpath( const char *wadfile, qboolean *already_loade
{ {
searchpath_t *search; searchpath_t *search;
wfile_t *wad = NULL; wfile_t *wad = NULL;
const char *ext = FS_FileExtension( wadfile ); const char *ext = COM_FileExtension( wadfile );
int errorcode = WAD_LOAD_COULDNT_OPEN; int errorcode = WAD_LOAD_COULDNT_OPEN;
for( search = fs_searchpaths; search; search = search->next ) 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; searchpath_t *search;
pack_t *pak = NULL; pack_t *pak = NULL;
const char *ext = FS_FileExtension( pakfile ); const char *ext = COM_FileExtension( pakfile );
int i, errorcode = PAK_LOAD_COULDNT_OPEN; int i, errorcode = PAK_LOAD_COULDNT_OPEN;
for( search = fs_searchpaths; search; search = search->next ) 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) // time to add in search list all the wads that contains in current pakfile (if do)
for( i = 0; i < pak->numfiles; i++ ) 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 ); Q_sprintf( fullpath, "%s/%s", pakfile, pak->files[i].name );
FS_AddWad_Fullpath( fullpath, NULL, flags ); 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 // add any PAK package in the directory
for( i = 0; i < list.numstrings; i++ ) 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] ); Q_sprintf( fullpath, "%s%s", dir, list.strings[i] );
FS_AddPak_Fullpath( fullpath, NULL, flags ); 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 // add any WAD package in the directory
for( i = 0; i < list.numstrings; i++ ) 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] ); Q_sprintf( fullpath, "%s%s", dir, list.strings[i] );
FS_AddWad_Fullpath( fullpath, NULL, flags ); FS_AddWad_Fullpath( fullpath, NULL, flags );
@ -702,79 +659,8 @@ FS_AddGameHierarchy
void FS_AddGameHierarchy( const char *dir, int flags ) void FS_AddGameHierarchy( const char *dir, int flags )
{ {
// Add the common game directory // Add the common game directory
if( dir && *dir ) FS_AddGameDirectory( va( "%s/", dir ), flags ); if( COM_CheckString( 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
} }
/* /*
@ -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 ) 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 // 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 // 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 // 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" )) else if( !Q_stricmp( token, "startmap" ))
{ {
pfile = COM_ParseFile( pfile, GameInfo->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" )) else if( !Q_stricmp( token, "trainmap" ) || !Q_stricmp( token, "trainingmap" ))
{ {
pfile = COM_ParseFile( pfile, GameInfo->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, "url_info" )) 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 ); pfile = COM_ParseFile( pfile, GameInfo->iconpath );
COM_FixSlashes( GameInfo->iconpath ); COM_FixSlashes( GameInfo->iconpath );
FS_DefaultExtension( GameInfo->iconpath, ".ico" ); COM_DefaultExtension( GameInfo->iconpath, ".ico" );
} }
else if( !Q_stricmp( token, "type" )) 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 ) static qboolean FS_ReadGameInfo( const char *filepath, const char *gamedir, gameinfo_t *GameInfo )
{ {
char *afile, *pfile; char *afile, *pfile;
@ -1233,17 +1124,17 @@ static qboolean FS_ReadGameInfo( const char *filepath, const char *gamedir, game
else if( !Q_stricmp( token, "startmap" )) else if( !Q_stricmp( token, "startmap" ))
{ {
pfile = COM_ParseFile( pfile, GameInfo->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" )) else if( !Q_stricmp( token, "trainmap" ))
{ {
pfile = COM_ParseFile( pfile, GameInfo->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" )) else if( !Q_stricmp( token, "icon" ))
{ {
pfile = COM_ParseFile( pfile, GameInfo->iconpath ); pfile = COM_ParseFile( pfile, GameInfo->iconpath );
FS_DefaultExtension( GameInfo->iconpath, ".ico" ); COM_DefaultExtension( GameInfo->iconpath, ".ico" );
} }
else if( !Q_stricmp( token, "url_info" )) 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 // quick reject by filetype
if( type == TYP_NONE ) continue; if( type == TYP_NONE ) continue;
FS_ExtractFilePath( name, wadname ); COM_ExtractFilePath( name, wadname );
wadfolder[0] = '\0'; wadfolder[0] = '\0';
if( Q_strlen( wadname )) if( Q_strlen( wadname ))
{ {
FS_FileBase( wadname, wadname ); COM_FileBase( wadname, wadname );
Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); Q_strncpy( wadfolder, wadname, sizeof( wadfolder ));
FS_DefaultExtension( wadname, ".wad" ); COM_DefaultExtension( wadname, ".wad" );
anywadname = false; anywadname = false;
} }
// make wadname from wad fullpath // make wadname from wad fullpath
FS_FileBase( search->wad->filename, shortname ); COM_FileBase( search->wad->filename, shortname );
FS_DefaultExtension( shortname, ".wad" ); COM_DefaultExtension( shortname, ".wad" );
// quick reject by wadname // quick reject by wadname
if( !anywadname && Q_stricmp( wadname, shortname )) 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, // NOTE: we can't using long names for wad,
// because we using original wad names[16]; // because we using original wad names[16];
FS_FileBase( name, shortname ); COM_FileBase( name, shortname );
lump = W_FindLump( search->wad, shortname, type ); 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 FS_FileExists
@ -2484,7 +2332,7 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
} }
dllpath[i] = '\0'; 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 ); search = FS_FindFile( dllpath, &index, false );
if( !search ) if( !search )
@ -2769,21 +2617,21 @@ search_t *FS_Search( const char *pattern, int caseinsensitive, int gamedironly )
// quick reject by filetype // quick reject by filetype
if( type == TYP_NONE ) continue; if( type == TYP_NONE ) continue;
FS_ExtractFilePath( pattern, wadname ); COM_ExtractFilePath( pattern, wadname );
FS_FileBase( pattern, wadpattern ); COM_FileBase( pattern, wadpattern );
wadfolder[0] = '\0'; wadfolder[0] = '\0';
if( Q_strlen( wadname )) if( Q_strlen( wadname ))
{ {
FS_FileBase( wadname, wadname ); COM_FileBase( wadname, wadname );
Q_strncpy( wadfolder, wadname, sizeof( wadfolder )); Q_strncpy( wadfolder, wadname, sizeof( wadfolder ));
FS_DefaultExtension( wadname, ".wad" ); COM_DefaultExtension( wadname, ".wad" );
anywadname = false; anywadname = false;
} }
// make wadname from wad fullpath // make wadname from wad fullpath
FS_FileBase( searchpath->wad->filename, temp2 ); COM_FileBase( searchpath->wad->filename, temp2 );
FS_DefaultExtension( temp2, ".wad" ); COM_DefaultExtension( temp2, ".wad" );
// quick reject by wadname // quick reject by wadname
if( !anywadname && Q_stricmp( wadname, temp2 )) 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 // build path: wadname/lumpname.ext
Q_snprintf( temp2, sizeof(temp2), "%s/%s", wadfolder, temp ); 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 ); stringlistappend( &resultlist, temp2 );
} }
} }
@ -2946,7 +2794,7 @@ Extracts file type from extension
*/ */
static char W_TypeFromExt( const char *lumpname ) static char W_TypeFromExt( const char *lumpname )
{ {
const char *ext = FS_FileExtension( lumpname ); const char *ext = COM_FileExtension( lumpname );
const wadtype_t *type; const wadtype_t *type;
// we not known about filetype, so match only by filename // we not known about filetype, so match only by filename
@ -2999,7 +2847,7 @@ char W_HintFromSuf( const char *lumpname )
const wadtype_t *hint; const wadtype_t *hint;
// trying to extract hint from the name // trying to extract hint from the name
FS_FileBase( lumpname, barename ); COM_FileBase( lumpname, barename );
namelen = Q_strlen( barename ); namelen = Q_strlen( barename );
if( namelen <= HINT_NAMELEN ) if( namelen <= HINT_NAMELEN )
@ -3037,7 +2885,7 @@ static dlumpinfo_t *W_FindLump( wfile_t *wad, const char *name, const char match
return NULL; return NULL;
// trying to extract hint from the name // trying to extract hint from the name
FS_FileBase( name, barename ); COM_FileBase( name, barename );
namelen = Q_strlen( barename ); namelen = Q_strlen( barename );
if( namelen > HINT_NAMELEN ) 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) // 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 ); 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 ) if( wad->handle == NULL )
{ {

View File

@ -29,7 +29,6 @@ HINSTANCE hCurrent; // hinstance of current .dll
host_parm_t host; // host parms host_parm_t host; // host parms
sysinfo_t SI; sysinfo_t SI;
convar_t *host_serverstate;
convar_t *host_gameloaded; convar_t *host_gameloaded;
convar_t *host_clientloaded; convar_t *host_clientloaded;
convar_t *host_limitlocal; convar_t *host_limitlocal;
@ -38,12 +37,6 @@ convar_t *host_framerate;
convar_t *con_gamemaps; convar_t *con_gamemaps;
convar_t *build, *ver; 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 ) int Host_CompareFileTime( long ft1, long ft2 )
{ {
if( ft1 < ft2 ) if( ft1 < ft2 )
@ -59,9 +52,7 @@ int Host_CompareFileTime( long ft1, long ft2 )
void Host_ShutdownServer( void ) void Host_ShutdownServer( void )
{ {
if( !SV_Initialized( )) return; SV_Shutdown( "Server was killed\n" );
Q_strncpy( host.finalmsg, "Server was killed", MAX_STRING );
SV_Shutdown( false );
} }
/* /*
@ -105,13 +96,8 @@ void Host_EndGame( qboolean abort, const char *message, ... )
va_end( argptr ); va_end( argptr );
MsgDev( D_INFO, "Host_EndGame: %s\n", string ); 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(); CL_Disconnect();
// recreate world if needs // recreate world if needs
@ -135,16 +121,6 @@ void Host_AbortCurrentFrame( void )
longjmp( host.abortframe, 1 ); longjmp( host.abortframe, 1 );
} }
/*
==================
Host_SetServerState
==================
*/
void Host_SetServerState( int state )
{
Cvar_FullSet( "host_serverstate", va( "%i", state ), FCVAR_READ_ONLY );
}
/* /*
================== ==================
Host_CheckSleep Host_CheckSleep
@ -161,7 +137,7 @@ void Host_CheckSleep( void )
{ {
if( host.status == HOST_NOFOCUS ) if( host.status == HOST_NOFOCUS )
{ {
if( Host_ServerState() && CL_IsInGame( )) if( SV_Active() && CL_IsInGame( ))
Sys_Sleep( 1 ); // listenserver Sys_Sleep( 1 ); // listenserver
else Sys_Sleep( 20 ); // sleep 20 ms otherwise 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 )); 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 ); f = FS_LoadFile( cfgpath, &len, false );
if( !f ) if( !f )
@ -340,7 +316,7 @@ qboolean Host_RegisterDecal( const char *name, int *count )
if( !name || !*name ) if( !name || !*name )
return 0; return 0;
FS_FileBase( name, shortname ); COM_FileBase( name, shortname );
for( i = 1; i < MAX_DECALS && host.draw_decals[i][0]; i++ ) 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 // clearing cmd buffer to prevent execute any commands
Cbuf_Clear(); Cbuf_Clear();
SV_Shutdown( false ); Host_ShutdownServer();
CL_Drop(); // drop clients CL_Drop(); // drop clients
// recreate world if needs // recreate world if needs
@ -810,9 +786,9 @@ void Host_InitCommon( const char *hostname, qboolean bChangeGame )
// we can specified custom name, from Sys_NewInstance // we can specified custom name, from Sys_NewInstance
if( GetModuleFileName( NULL, szTemp, sizeof( szTemp )) && !host.change_game ) 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 )) if( Q_stricmp( host.rootdir, szRootPath ))
{ {
Q_strncpy( host.rootdir, szRootPath, sizeof( host.rootdir )); 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_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_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_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_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" ); 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 ) if( host.type == HOST_NORMAL )
Host_WriteConfig(); Host_WriteConfig();
SV_Shutdown( false ); SV_Shutdown( "" );
CL_Shutdown(); CL_Shutdown();
Mod_Shutdown(); Mod_Shutdown();

View File

@ -100,8 +100,8 @@ void HPAK_CreatePak( const char *filename, resource_t *pResource, byte *pData, f
} }
Q_strncpy( pakname, filename, sizeof( pakname )); Q_strncpy( pakname, filename, sizeof( pakname ));
FS_StripExtension( pakname ); COM_StripExtension( pakname );
FS_DefaultExtension( pakname, ".hpk" ); COM_DefaultExtension( pakname, ".hpk" );
MsgDev( D_INFO, "creating HPAK %s.\n", pakname ); 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 )); Q_strncpy( srcname, name, sizeof( srcname ));
FS_StripExtension( srcname ); COM_StripExtension( srcname );
FS_DefaultExtension( srcname, ".hpk" ); COM_DefaultExtension( srcname, ".hpk" );
file_src = FS_Open( srcname, "rb", false ); 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 )); Q_strncpy( dstname, srcname, sizeof( dstname ));
FS_StripExtension( dstname ); COM_StripExtension( dstname );
FS_DefaultExtension( dstname, ".hp2" ); COM_DefaultExtension( dstname, ".hp2" );
file_dst = FS_Open( dstname, "w+b", false ); file_dst = FS_Open( dstname, "w+b", false );
@ -379,8 +379,8 @@ static qboolean HPAK_Validate( const char *filename, qboolean quiet )
return true; return true;
Q_strncpy( pakname, filename, sizeof( pakname )); Q_strncpy( pakname, filename, sizeof( pakname ));
FS_StripExtension( pakname ); COM_StripExtension( pakname );
FS_DefaultExtension( pakname, ".hpk" ); COM_DefaultExtension( pakname, ".hpk" );
f = FS_Open( pakname, "rb", false ); f = FS_Open( pakname, "rb", false );
if( !f ) if( !f )
@ -480,8 +480,8 @@ void HPAK_CheckIntegrity( const char *filename )
return; return;
Q_strncpy( pakname, filename, sizeof( pakname )); Q_strncpy( pakname, filename, sizeof( pakname ));
FS_StripExtension( pakname ); COM_StripExtension( pakname );
FS_DefaultExtension( pakname, ".hpk" ); COM_DefaultExtension( pakname, ".hpk" );
HPAK_ValidatePak( pakname ); HPAK_ValidatePak( pakname );
} }
@ -498,8 +498,8 @@ void HPAK_CheckSize( const char *filename )
return; return;
Q_strncpy( pakname, filename, sizeof( pakname )); Q_strncpy( pakname, filename, sizeof( pakname ));
FS_StripExtension( pakname ); COM_StripExtension( pakname );
FS_DefaultExtension( pakname, ".hpk" ); COM_DefaultExtension( pakname, ".hpk" );
if( FS_FileSize( pakname, false ) > ( maxsize * 1000000 )) 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 )); Q_strncpy( pakname, filename, sizeof( pakname ));
FS_StripExtension( pakname ); COM_StripExtension( pakname );
FS_DefaultExtension( pakname, ".hpk" ); COM_DefaultExtension( pakname, ".hpk" );
f = FS_Open( pakname, "rb", false ); f = FS_Open( pakname, "rb", false );
if( !f ) return false; if( !f ) return false;
@ -581,8 +581,8 @@ static qboolean HPAK_ResourceForIndex( const char *filename, int index, resource
return false; return false;
Q_strncpy( pakname, filename, sizeof( pakname )); Q_strncpy( pakname, filename, sizeof( pakname ));
FS_StripExtension( pakname ); COM_StripExtension( pakname );
FS_DefaultExtension( pakname, ".hpk" ); COM_DefaultExtension( pakname, ".hpk" );
f = FS_Open( pakname, "rb", false ); f = FS_Open( pakname, "rb", false );
if( !f ) if( !f )
@ -668,8 +668,8 @@ qboolean HPAK_GetDataPointer( const char *filename, resource_t *pResource, byte
} }
Q_strncpy( pakname, filename, sizeof( pakname )); Q_strncpy( pakname, filename, sizeof( pakname ));
FS_StripExtension( pakname ); COM_StripExtension( pakname );
FS_DefaultExtension( pakname, ".hpk" ); COM_DefaultExtension( pakname, ".hpk" );
f = FS_Open( pakname, "rb", false ); f = FS_Open( pakname, "rb", false );
if( !f ) return false; if( !f ) return false;
@ -750,8 +750,8 @@ void HPAK_RemoveLump( const char *name, resource_t *pResource )
HPAK_FlushHostQueue(); HPAK_FlushHostQueue();
Q_strncpy( read_path, name, sizeof( read_path )); Q_strncpy( read_path, name, sizeof( read_path ));
FS_StripExtension( read_path ); COM_StripExtension( read_path );
FS_DefaultExtension( read_path, ".hpk" ); COM_DefaultExtension( read_path, ".hpk" );
file_src = FS_Open( read_path, "rb", false ); file_src = FS_Open( read_path, "rb", false );
if( !file_src ) 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 )); Q_strncpy( save_path, read_path, sizeof( save_path ));
FS_StripExtension( save_path ); COM_StripExtension( save_path );
FS_DefaultExtension( save_path, ".hp2" ); COM_DefaultExtension( save_path, ".hp2" );
file_dst = FS_Open( save_path, "w+b", false ); file_dst = FS_Open( save_path, "w+b", false );
if( !file_dst ) if( !file_dst )
@ -881,8 +881,8 @@ void HPAK_List_f( void )
HPAK_FlushHostQueue(); HPAK_FlushHostQueue();
Q_strncpy( pakname, Cmd_Argv( 1 ), sizeof( pakname )); Q_strncpy( pakname, Cmd_Argv( 1 ), sizeof( pakname ));
FS_StripExtension( pakname ); COM_StripExtension( pakname );
FS_DefaultExtension( pakname, ".hpk" ); COM_DefaultExtension( pakname, ".hpk" );
Msg( "Contents for %s.\n", pakname ); Msg( "Contents for %s.\n", pakname );
f = FS_Open( pakname, "rb", false ); f = FS_Open( pakname, "rb", false );
@ -927,7 +927,7 @@ void HPAK_List_f( void )
for( nCurrent = 0; nCurrent < directory.count; nCurrent++ ) for( nCurrent = 0; nCurrent < directory.count; nCurrent++ )
{ {
entry = &directory.entries[nCurrent]; entry = &directory.entries[nCurrent];
FS_FileBase( entry->resource.szFileName, lumpname ); COM_FileBase( entry->resource.szFileName, lumpname );
type = HPAK_TypeFromIndex( entry->resource.type ); type = HPAK_TypeFromIndex( entry->resource.type );
size = Q_memprint( entry->resource.nDownloadSize ); size = Q_memprint( entry->resource.nDownloadSize );
@ -973,8 +973,8 @@ void HPAK_Extract_f( void )
HPAK_FlushHostQueue(); HPAK_FlushHostQueue();
Q_strncpy( pakname, Cmd_Argv( 1 ), sizeof( pakname )); Q_strncpy( pakname, Cmd_Argv( 1 ), sizeof( pakname ));
FS_StripExtension( pakname ); COM_StripExtension( pakname );
FS_DefaultExtension( pakname, ".hpk" ); COM_DefaultExtension( pakname, ".hpk" );
Msg( "Contents for %s.\n", pakname ); Msg( "Contents for %s.\n", pakname );
f = FS_Open( pakname, "rb", false ); f = FS_Open( pakname, "rb", false );
@ -1023,7 +1023,7 @@ void HPAK_Extract_f( void )
if( nIndex != -1 && nIndex != nCurrent ) if( nIndex != -1 && nIndex != nCurrent )
continue; continue;
FS_FileBase( entry->resource.szFileName, lumpname ); COM_FileBase( entry->resource.szFileName, lumpname );
type = HPAK_TypeFromIndex( entry->resource.type ); type = HPAK_TypeFromIndex( entry->resource.type );
size = Q_memprint( entry->resource.nDownloadSize ); size = Q_memprint( entry->resource.nDownloadSize );

View File

@ -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 ) 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; string path, loadname, sidename;
qboolean anyformat = true; qboolean anyformat = true;
int i, filesize = 0; 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 )) if( !Q_stricmp( format->ext, ext ))
{ {
FS_StripExtension( loadname ); COM_StripExtension( loadname );
anyformat = false; anyformat = false;
break; break;
} }
@ -364,7 +364,7 @@ writes image as any known format
*/ */
qboolean FS_SaveImage( const char *filename, rgbdata_t *pix ) 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; qboolean anyformat = !Q_stricmp( ext, "" ) ? true : false;
string path, savename; string path, savename;
const savepixformat_t *format; const savepixformat_t *format;
@ -377,7 +377,7 @@ qboolean FS_SaveImage( const char *filename, rgbdata_t *pix )
} }
Q_strncpy( savename, filename, sizeof( savename )); 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)) if( pix->flags & (IMAGE_CUBEMAP|IMAGE_SKYBOX))
{ {

View File

@ -268,7 +268,7 @@ static int BuildImportTable( MEMORYMODULE *module )
void *handle; void *handle;
libname = (LPCSTR)CALCULATE_ADDRESS( codeBase, importDesc->Name ); libname = (LPCSTR)CALCULATE_ADDRESS( codeBase, importDesc->Name );
handle = Com_LoadLibraryExt( libname, false, true ); handle = COM_LoadLibraryExt( libname, false, true );
if( handle == NULL ) if( handle == NULL )
{ {
@ -297,13 +297,13 @@ static int BuildImportTable( MEMORYMODULE *module )
if( IMAGE_SNAP_BY_ORDINAL( *thunkRef )) if( IMAGE_SNAP_BY_ORDINAL( *thunkRef ))
{ {
LPCSTR funcName = (LPCSTR)IMAGE_ORDINAL( *thunkRef ); LPCSTR funcName = (LPCSTR)IMAGE_ORDINAL( *thunkRef );
*funcRef = (DWORD)Com_GetProcAddress( handle, funcName ); *funcRef = (DWORD)COM_GetProcAddress( handle, funcName );
} }
else else
{ {
PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)CALCULATE_ADDRESS( codeBase, *thunkRef ); PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)CALCULATE_ADDRESS( codeBase, *thunkRef );
LPCSTR funcName = (LPCSTR)&thunkData->Name; LPCSTR funcName = (LPCSTR)&thunkData->Name;
*funcRef = (DWORD)Com_GetProcAddress( handle, funcName ); *funcRef = (DWORD)COM_GetProcAddress( handle, funcName );
} }
if( *funcRef == 0 ) if( *funcRef == 0 )
@ -340,9 +340,7 @@ static void MemoryFreeLibrary( void *hInstance )
for( i = 0; i < module->numModules; i++ ) for( i = 0; i < module->numModules; i++ )
{ {
if( module->modules[i] != NULL ) if( module->modules[i] != NULL )
{ COM_FreeLibrary( module->modules[i] );
Com_FreeLibrary( module->modules[i] );
}
} }
Mem_Free( module->modules ); // Mem_Realloc end Mem_Free( module->modules ); // Mem_Realloc end
} }
@ -742,7 +740,7 @@ qboolean LibraryLoadSymbols( dll_user_t *hInst )
void *fn_offset; void *fn_offset;
index = hInst->ordinals[i]; 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]; hInst->funcBase = (dword)(fn_offset) - hInst->funcs[index];
break; break;
} }
@ -762,12 +760,12 @@ table_error:
/* /*
================ ================
Com_LoadLibrary COM_LoadLibrary
smart dll loader - can loading dlls from pack or wad files 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; dll_user_t *hInst;
@ -789,7 +787,7 @@ void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolea
if( !hInst->hInstance ) if( !hInst->hInstance )
{ {
MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s - failed\n", dllname ); MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s - failed\n", dllname );
Com_FreeLibrary( hInst ); COM_FreeLibrary( hInst );
return NULL; return NULL;
} }
@ -799,7 +797,7 @@ void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolea
if( !LibraryLoadSymbols( hInst )) if( !LibraryLoadSymbols( hInst ))
{ {
MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s - failed\n", dllname ); MsgDev( D_NOTE, "Sys_LoadLibrary: Loading %s - failed\n", dllname );
Com_FreeLibrary( hInst ); COM_FreeLibrary( hInst );
return NULL; return NULL;
} }
} }
@ -809,12 +807,12 @@ void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolea
return hInst; 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; 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 )); 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; dll_user_t *hInst = (dll_user_t *)hInstance;
@ -852,7 +850,7 @@ void Com_FreeLibrary( void *hInstance )
Mem_Free( hInst ); // done 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; dll_user_t *hInst = (dll_user_t *)hInstance;
int i, index; int i, index;
@ -872,7 +870,7 @@ dword Com_FunctionFromName( void *hInstance, const char *pName )
return 0; 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; dll_user_t *hInst = (dll_user_t *)hInstance;
int i, index; int i, index;

View File

@ -151,11 +151,11 @@ typedef struct dll_user_s
} dll_user_t; } dll_user_t;
dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath ); dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath );
void *Com_LoadLibrary( const char *dllname, int build_ordinals_table ); void *COM_LoadLibrary( const char *dllname, int build_ordinals_table );
void *Com_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolean directpath ); void *COM_LoadLibraryExt( const char *dllname, int build_ordinals_table, qboolean directpath );
void *Com_GetProcAddress( void *hInstance, const char *name ); void *COM_GetProcAddress( void *hInstance, const char *name );
const char *Com_NameForFunction( void *hInstance, dword function ); const char *COM_NameForFunction( void *hInstance, dword function );
dword Com_FunctionFromName( void *hInstance, const char *pName ); dword COM_FunctionFromName( void *hInstance, const char *pName );
void Com_FreeLibrary( void *hInstance ); void COM_FreeLibrary( void *hInstance );
#endif//LIBRARY_H #endif//LIBRARY_H

View File

@ -1236,7 +1236,7 @@ static qboolean Mod_LoadColoredLighting( dbspmodel_t *bmod )
size_t litdatasize; size_t litdatasize;
byte *in; byte *in;
FS_FileBase( loadmodel->name, modelname ); COM_FileBase( loadmodel->name, modelname );
Q_snprintf( path, sizeof( path ), "maps/%s.lit", modelname ); Q_snprintf( path, sizeof( path ), "maps/%s.lit", modelname );
// make sure what deluxemap is actual // make sure what deluxemap is actual
@ -1244,7 +1244,7 @@ static qboolean Mod_LoadColoredLighting( dbspmodel_t *bmod )
return false; return false;
if( iCompare < 0 ) // this may happens if level-designer used -onlyents key for hlcsg 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 ); 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 ) 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 ); Mem_Free( in );
return false; return false;
} }
@ -1260,7 +1259,6 @@ static qboolean Mod_LoadColoredLighting( dbspmodel_t *bmod )
// skip header bytes // skip header bytes
litdatasize -= 8; litdatasize -= 8;
MsgDev( D_INFO, "Mod_LoadColoredLighting: %s loaded\n", path );
loadmodel->lightdata = Mem_Alloc( loadmodel->mempool, litdatasize ); loadmodel->lightdata = Mem_Alloc( loadmodel->mempool, litdatasize );
memcpy( loadmodel->lightdata, in + 8, litdatasize ); memcpy( loadmodel->lightdata, in + 8, litdatasize );
SetBits( loadmodel->flags, MODEL_COLORED_LIGHTING ); SetBits( loadmodel->flags, MODEL_COLORED_LIGHTING );
@ -1286,7 +1284,7 @@ static void Mod_LoadDeluxemap( dbspmodel_t *bmod )
if( !FBitSet( host.features, ENGINE_LOAD_DELUXEDATA )) if( !FBitSet( host.features, ENGINE_LOAD_DELUXEDATA ))
return; return;
FS_FileBase( loadmodel->name, modelname ); COM_FileBase( loadmodel->name, modelname );
Q_snprintf( path, sizeof( path ), "maps/%s.dlit", modelname ); Q_snprintf( path, sizeof( path ), "maps/%s.dlit", modelname );
// make sure what deluxemap is actual // make sure what deluxemap is actual
@ -1294,7 +1292,7 @@ static void Mod_LoadDeluxemap( dbspmodel_t *bmod )
return; return;
if( iCompare < 0 ) // this may happens if level-designer used -onlyents key for hlcsg 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 ); 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 ) 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 ); Mem_Free( in );
return; return;
} }
@ -1312,12 +1309,11 @@ static void Mod_LoadDeluxemap( dbspmodel_t *bmod )
if( deluxdatasize != bmod->lightdatasize ) 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 ); Mem_Free( in );
return; return;
} }
MsgDev( D_INFO, "Mod_LoadDeluxemap: %s loaded\n", path );
bmod->deluxedata_out = Mem_Alloc( loadmodel->mempool, deluxdatasize ); bmod->deluxedata_out = Mem_Alloc( loadmodel->mempool, deluxdatasize );
memcpy( bmod->deluxedata_out, in + 8, deluxdatasize ); memcpy( bmod->deluxedata_out, in + 8, deluxdatasize );
bmod->deluxdatasize = deluxdatasize; bmod->deluxdatasize = deluxdatasize;
@ -1544,7 +1540,7 @@ static void Mod_LoadEntities( dbspmodel_t *bmod )
for( pszWadFile = strtok( wadstring, ";" ); pszWadFile != NULL; pszWadFile = strtok( NULL, ";" )) for( pszWadFile = strtok( wadstring, ";" ); pszWadFile != NULL; pszWadFile = strtok( NULL, ";" ))
{ {
COM_FixSlashes( pszWadFile ); COM_FixSlashes( pszWadFile );
FS_FileBase( pszWadFile, token ); COM_FileBase( pszWadFile, token );
// make sure what wad is really exist // make sure what wad is really exist
if( FS_FileExists( va( "%s.wad", token ), false )) 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); int size = (int)sizeof( mip_t ) + ((mt->width * mt->height * 85)>>6);
if( custom_palette ) size += sizeof( short ) + 768; 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 ); 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 // check for luma texture
if( FBitSet( R_GetTexture( tx->gl_texturenum )->flags, TF_HAS_LUMA )) 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 ) 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 ); bmod->deluxedata_out = Mem_Alloc( loadmodel->mempool, bmod->deluxdatasize );
memcpy( bmod->deluxedata_out, bmod->deluxdata, 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 ); bmod->shadowdata_out = Mem_Alloc( loadmodel->mempool, bmod->shadowdatasize );
memcpy( bmod->shadowdata_out, bmod->shadowdata, 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 ) 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 return false; // there were errors, we can't load this map
} }
else if( loadstat.numwarnings ) 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 // load into heap
Mod_LoadEntities( bmod ); Mod_LoadEntities( bmod );
@ -2697,13 +2691,13 @@ qboolean Mod_TestBmodelLumps( const char *name, const byte *mod_base, qboolean s
if( loadstat.numerrors ) if( loadstat.numerrors )
{ {
if( !FBitSet( flags, LUMP_SILENT )) 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 return false; // there were errors, we can't load this map
} }
else if( loadstat.numwarnings ) else if( loadstat.numwarnings )
{ {
if( !FBitSet( flags, LUMP_SILENT )) 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; return true;

View File

@ -97,8 +97,6 @@ typedef struct
typedef struct typedef struct
{ {
int load_sequence; // increace each map change
qboolean loading; // true if worldmodel is loading qboolean loading; // true if worldmodel is loading
int flags; // misc flags 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_NeedCRC( const char *name, qboolean needCRC );
void Mod_PurgeStudioCache( void ); void Mod_PurgeStudioCache( void );
void Mod_FreeUnused( void ); void Mod_FreeUnused( void );
void Mod_ClearAll( void );
// //
// mod_bmodel.c // 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_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 *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_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 ); int Mod_HitgroupForStudioHull( int index );
void Mod_ClearStudioCache( void ); void Mod_ClearStudioCache( void );

View File

@ -720,6 +720,189 @@ qboolean Mod_GetStudioBounds( const char *name, vec3_t mins, vec3_t maxs )
return result; 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 = static sv_blending_interface_t gBlendAPI =
{ {
SV_BLENDING_INTERFACE_VERSION, SV_BLENDING_INTERFACE_VERSION,
@ -747,7 +930,7 @@ void Mod_InitStudioAPI( void )
pBlendAPI = &gBlendAPI; 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 )) 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 ); MsgDev( D_REPORT, "SV_LoadProgs: ^2initailized Server Blending interface ^7ver. %i\n", SV_BLENDING_INTERFACE_VERSION );

View File

@ -50,21 +50,20 @@ static void Mod_Modellist_f( void )
int i, nummodels; int i, nummodels;
model_t *mod; model_t *mod;
Msg( "\n" ); Con_Printf( "\n" );
Msg( "-----------------------------------\n" ); Con_Printf( "-----------------------------------\n" );
for( i = nummodels = 0, mod = mod_known; i < mod_numknown; i++, mod++ ) for( i = nummodels = 0, mod = mod_known; i < mod_numknown; i++, mod++ )
{ {
if( !mod->name[0] ) if( !mod->name[0] )
continue; // free slot continue; // free slot
Con_Printf( "%s\n", mod->name );
Msg( "%s%s\n", mod->name, (mod->type == mod_bad) ? " (DEFAULTED)" : "" );
nummodels++; nummodels++;
} }
Msg( "-----------------------------------\n" ); Con_Printf( "-----------------------------------\n" );
Msg( "%i total models\n", nummodels ); Con_Printf( "%i total models\n", nummodels );
Msg( "\n" ); Con_Printf( "\n" );
} }
/* /*
@ -164,23 +163,6 @@ void Mod_FreeAll( void )
mod_numknown = 0; 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 Mod_ClearUserData
@ -234,7 +216,7 @@ model_t *Mod_FindName( const char *filename, qboolean trackCRC )
{ {
if( !Q_stricmp( mod->name, modname )) if( !Q_stricmp( mod->name, modname ))
{ {
if( mod->mempool ) if( mod->mempool || mod->name[0] == '*' )
mod->needload = NL_PRESENT; mod->needload = NL_PRESENT;
else mod->needload = NL_NEEDS_LOADED; 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 )); Q_strncpy( mod->name, modname, sizeof( mod->name ));
if( trackCRC ) mod_crcinfo[i].flags = FCRC_SHOULD_CHECKSUM; if( trackCRC ) mod_crcinfo[i].flags = FCRC_SHOULD_CHECKSUM;
else mod_crcinfo[i].flags = 0; else mod_crcinfo[i].flags = 0;
mod->needload = NL_NEEDS_LOADED;
mod_crcinfo[i].initialCRC = 0; mod_crcinfo[i].initialCRC = 0;
return mod; return mod;
@ -291,6 +274,8 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
return mod; return mod;
} }
ASSERT( mod->needload == NL_NEEDS_LOADED );
// store modelname to show error // store modelname to show error
Q_strncpy( tempname, mod->name, sizeof( tempname )); Q_strncpy( tempname, mod->name, sizeof( tempname ));
COM_FixSlashes( tempname ); COM_FixSlashes( tempname );
@ -307,8 +292,8 @@ model_t *Mod_LoadModel( model_t *mod, qboolean crash )
return NULL; return NULL;
} }
MsgDev( D_NOTE, "Mod_LoadModel: %s\n", mod->name ); Con_DPrintf( "loading %s\n", mod->name );
mod->needload = world.load_sequence; // register mod mod->needload = NL_PRESENT;
mod->type = mod_bad; mod->type = mod_bad;
loadmodel = mod; loadmodel = mod;
@ -425,6 +410,7 @@ void Mod_PurgeStudioCache( void )
mod_known[i].submodels = NULL; mod_known[i].submodels = NULL;
if( mod_known[i].name[0] == '*' ) if( mod_known[i].name[0] == '*' )
Mod_FreeModel( &mod_known[i] ); Mod_FreeModel( &mod_known[i] );
mod_known[i].needload = NL_UNREFERENCED;
} }
Mem_EmptyPool( com_studiocache ); Mem_EmptyPool( com_studiocache );
@ -452,9 +438,6 @@ model_t *Mod_LoadWorld( const char *name, qboolean preload )
// release previois map // release previois map
Mod_FreeModel( mod_known ); // world is stuck on slot #0 always Mod_FreeModel( mod_known ); // world is stuck on slot #0 always
world.load_sequence++; // now all models are invalid
Mod_ClearAll();
// load the newmap // load the newmap
world.loading = true; world.loading = true;
pworld = Mod_FindName( name, false ); pworld = Mod_FindName( name, false );
@ -480,7 +463,7 @@ void Mod_FreeUnused( void )
for( i = 0, mod = mod_known; i < mod_numknown; i++, mod++ ) 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 ); Mod_FreeModel( mod );
} }
} }

View File

@ -143,7 +143,7 @@ void Netchan_ReportFlow( netchan_t *chan )
Q_strcpy( incoming, Q_pretifymem((float)chan->flow[FLOW_INCOMING].totalbytes, 3 )); Q_strcpy( incoming, Q_pretifymem((float)chan->flow[FLOW_INCOMING].totalbytes, 3 ));
Q_strcpy( outgoing, Q_pretifymem((float)chan->flow[FLOW_OUTGOING].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 );
} }
/* /*

View File

@ -653,7 +653,7 @@ static void NET_AdjustLag( void )
dt = bound( 0.0, dt, 0.1 ); dt = bound( 0.0, dt, 0.1 );
lasttime = host.realtime; lasttime = host.realtime;
if( host.developer >= D_ERROR || !net_fakelag->value ) if( host.developer || !net_fakelag->value )
{ {
if( net_fakelag->value != net.fakelag ) if( net_fakelag->value != net.fakelag )
{ {
@ -668,7 +668,7 @@ static void NET_AdjustLag( void )
} }
else 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 ); Cvar_SetValue( "fakelag", 0.0 );
net.fakelag = 0.0f; net.fakelag = 0.0f;
} }
@ -1181,8 +1181,7 @@ NET_OpenIP
*/ */
static void NET_OpenIP( void ) static void NET_OpenIP( void )
{ {
int port, sv_port = 0, cl_port = 0; int port, sv_port = 0, cl_port = 0;
static qboolean bFirst = true;
if( net.ip_sockets[NS_SERVER] == INVALID_SOCKET ) 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 ); net.ip_sockets[NS_CLIENT] = NET_IPSocket( net_ipname->string, PORT_ANY, false );
cl_port = port; 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 else
{ {
net_local.port = address.sin_port; 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 ); Cvar_FullSet( "net_address", va( NET_AdrToString( net_local )), FCVAR_READ_ONLY );
} }
} }
@ -1272,7 +1265,7 @@ void NET_GetLocalAddress( void )
} }
else else
{ {
MsgDev( D_INFO, "TCP/IP Disabled.\n" ); Con_Printf( "TCP/IP Disabled.\n" );
} }
} }
@ -1428,9 +1421,7 @@ void NET_Init( void )
return; return;
} }
i = pWSAStartup( MAKEWORD( 1, 1 ), &net.winsockdata ); if( pWSAStartup( MAKEWORD( 1, 1 ), &net.winsockdata ))
if( i )
{ {
MsgDev( D_ERROR, "network initialization failed.\n" ); MsgDev( D_ERROR, "network initialization failed.\n" );
NET_FreeWinSock(); NET_FreeWinSock();

View File

@ -23,7 +23,7 @@ GNU General Public License for more details.
#define svc_nop 1 // does nothing #define svc_nop 1 // does nothing
#define svc_disconnect 2 // kick client from server #define svc_disconnect 2 // kick client from server
#define svc_event 3 // playback event queue #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_setview 5 // [short] entity number
#define svc_sound 6 // <see code> #define svc_sound 6 // <see code>
#define svc_time 7 // [float] server time #define svc_time 7 // [float] server time

View File

@ -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 ) 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; string path, loadname;
qboolean anyformat = true; qboolean anyformat = true;
int filesize = 0; 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 )) if( !Q_stricmp( format->ext, ext ))
{ {
FS_StripExtension( loadname ); COM_StripExtension( loadname );
anyformat = false; anyformat = false;
break; break;
} }
@ -150,7 +150,7 @@ open and reading basic info from sound stream
*/ */
stream_t *FS_OpenStream( const char *filename ) stream_t *FS_OpenStream( const char *filename )
{ {
const char *ext = FS_FileExtension( filename ); const char *ext = COM_FileExtension( filename );
string path, loadname; string path, loadname;
qboolean anyformat = true; qboolean anyformat = true;
const streamfmt_t *format; const streamfmt_t *format;
@ -167,7 +167,7 @@ stream_t *FS_OpenStream( const char *filename )
{ {
if( !Q_stricmp( format->ext, ext )) if( !Q_stricmp( format->ext, ext ))
{ {
FS_StripExtension( loadname ); COM_StripExtension( loadname );
anyformat = false; anyformat = false;
break; break;
} }

View File

@ -587,6 +587,10 @@ SOURCE=.\client\client.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\common\com_strings.h
# End Source File
# Begin Source File
SOURCE=.\common\common.h SOURCE=.\common\common.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@ -136,10 +136,11 @@ typedef struct server_s
double time; // sv.time += sv.frametime double time; // sv.time += sv.frametime
double time_residual; // unclamped double time_residual; // unclamped
float frametime; // 1.0 / sv_fps->value 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 int hostflags; // misc server flags: predicting etc
CRC32_t worldmapCRC; CRC32_t worldmapCRC;
int progsCRC;
string name; // map name string name; // map name
string startspot; // player_start name on nextmap string startspot; // player_start name on nextmap
@ -378,7 +379,6 @@ typedef struct
char serverinfo[MAX_SERVERINFO_STRING]; char serverinfo[MAX_SERVERINFO_STRING];
char localinfo[MAX_LOCALINFO_STRING]; char localinfo[MAX_LOCALINFO_STRING];
double changelevel_next_time; // don't execute multiple changelevels at once time
int spawncount; // incremented each server start int spawncount; // incremented each server start
// used to check late spawns // used to check late spawns
sv_client_t *clients; // [svs.maxclients] sv_client_t *clients; // [svs.maxclients]
@ -458,7 +458,7 @@ extern convar_t *public_server;
// //
// sv_main.c // 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_DropClient( sv_client_t *drop );
void SV_UpdateMovevars( qboolean initialize ); void SV_UpdateMovevars( qboolean initialize );
int SV_ModelIndex( const char *name ); 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_Close( void );
void Log_Open( void ); void Log_Open( void );
void Log_PrintServerVars( void ); void Log_PrintServerVars( void );
void SV_ServerLog_f( sv_client_t *cl ); qboolean SV_ServerLog_f( sv_client_t *cl );
// //
// sv_save.c // sv_save.c

View File

@ -37,7 +37,7 @@ const char *clc_strings[clc_lastmsg+1] =
typedef struct ucmd_s typedef struct ucmd_s
{ {
const char *name; const char *name;
void (*func)( sv_client_t *cl ); qboolean (*func)( sv_client_t *cl );
} ucmd_t; } ucmd_t;
static int g_userid = 1; 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 )) if(( host.developer ) || ( svs.maxclients > 1 ))
{ {
MSG_BeginServerCmd( msg, svc_print ); 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 ); 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. 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]; byte msg_buf[MAX_INIT_MSG];
sv_client_t *cur; 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 )); MSG_Init( &msg, "New", msg_buf, sizeof( msg_buf ));
if( cl->state != cs_connected ) if( cl->state != cs_connected )
{ return false;
MsgDev( D_INFO, "'new' is not valid from the console\n" );
return;
}
// send the serverdata // send the serverdata
SV_SendServerdata( &msg, cl ); SV_SendServerdata( &msg, cl );
@ -1503,6 +1500,8 @@ void SV_New_f( sv_client_t *cl )
Netchan_CreateFragments( &cl->netchan, &msg ); Netchan_CreateFragments( &cl->netchan, &msg );
Netchan_FragSend( &cl->netchan ); Netchan_FragSend( &cl->netchan );
return true;
} }
/* /*
@ -1510,23 +1509,19 @@ void SV_New_f( sv_client_t *cl )
SV_WriteModels_f SV_WriteModels_f
================== ==================
*/ */
void SV_WriteModels_f( sv_client_t *cl ) static qboolean SV_WriteModels_f( sv_client_t *cl )
{ {
int start; int start;
string cmd; string cmd;
if( cl->state != cs_connected ) if( cl->state != cs_connected )
{ return false;
MsgDev( D_INFO, "'modellist' is not valid from the console\n" );
return;
}
// handle the case of a level changing while a client was connecting // handle the case of a level changing while a client was connecting
if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount ) if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount )
{ {
MsgDev( D_INFO, "'modellist' from different level\n" );
SV_New_f( cl ); SV_New_f( cl );
return; return true;
} }
start = Q_atoi( Cmd_Argv( 2 )); start = Q_atoi( Cmd_Argv( 2 ));
@ -1549,6 +1544,8 @@ void SV_WriteModels_f( sv_client_t *cl )
// send next command // send next command
MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext ); MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext );
MSG_WriteString( &cl->netchan.message, cmd ); MSG_WriteString( &cl->netchan.message, cmd );
return true;
} }
/* /*
@ -1556,23 +1553,19 @@ void SV_WriteModels_f( sv_client_t *cl )
SV_WriteSounds_f SV_WriteSounds_f
================== ==================
*/ */
void SV_WriteSounds_f( sv_client_t *cl ) static qboolean SV_WriteSounds_f( sv_client_t *cl )
{ {
int start; int start;
string cmd; string cmd;
if( cl->state != cs_connected ) if( cl->state != cs_connected )
{ return false;
MsgDev( D_INFO, "'soundlist' is not valid from the console\n" );
return;
}
// handle the case of a level changing while a client was connecting // handle the case of a level changing while a client was connecting
if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount ) if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount )
{ {
MsgDev( D_INFO, "'soundlist' from different level\n" );
SV_New_f( cl ); SV_New_f( cl );
return; return true;
} }
start = Q_atoi( Cmd_Argv( 2 )); start = Q_atoi( Cmd_Argv( 2 ));
@ -1595,6 +1588,8 @@ void SV_WriteSounds_f( sv_client_t *cl )
// send next command // send next command
MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext ); MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext );
MSG_WriteString( &cl->netchan.message, cmd ); MSG_WriteString( &cl->netchan.message, cmd );
return true;
} }
/* /*
@ -1602,23 +1597,19 @@ void SV_WriteSounds_f( sv_client_t *cl )
SV_WriteEvents_f SV_WriteEvents_f
================== ==================
*/ */
void SV_WriteEvents_f( sv_client_t *cl ) static qboolean SV_WriteEvents_f( sv_client_t *cl )
{ {
int start; int start;
string cmd; string cmd;
if( cl->state != cs_connected ) if( cl->state != cs_connected )
{ return false;
MsgDev( D_INFO, "'eventlist' is not valid from the console\n" );
return;
}
// handle the case of a level changing while a client was connecting // handle the case of a level changing while a client was connecting
if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount ) if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount )
{ {
MsgDev( D_INFO, "'eventlist' from different level\n" );
SV_New_f( cl ); SV_New_f( cl );
return; return true;
} }
start = Q_atoi( Cmd_Argv( 2 )); start = Q_atoi( Cmd_Argv( 2 ));
@ -1641,6 +1632,8 @@ void SV_WriteEvents_f( sv_client_t *cl )
// send next command // send next command
MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext ); MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext );
MSG_WriteString( &cl->netchan.message, cmd ); 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 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 ); SV_DropClient( cl );
return true;
} }
/* /*
@ -1662,9 +1656,10 @@ SV_ShowServerinfo_f
Dumps the serverinfo info string 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 ); Info_Print( svs.serverinfo );
return true;
} }
/* /*
@ -1672,30 +1667,32 @@ void SV_ShowServerinfo_f( sv_client_t *cl )
SV_Pause_f SV_Pause_f
================== ==================
*/ */
void SV_Pause_f( sv_client_t *cl ) static qboolean SV_Pause_f( sv_client_t *cl )
{ {
string message; string message;
if( UI_CreditsActive( )) return; if( UI_CreditsActive( ))
return true;
if( !sv_pausable->value ) if( !sv_pausable->value )
{ {
SV_ClientPrintf( cl, "Pause not allowed.\n" ); SV_ClientPrintf( cl, "Pause not allowed.\n" );
return; return true;
} }
if( FBitSet( cl->flags, FCL_HLTV_PROXY )) if( FBitSet( cl->flags, FCL_HLTV_PROXY ))
{ {
SV_ClientPrintf( cl, "Spectators can not pause.\n" ); 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 ); 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 ); else Q_snprintf( message, MAX_STRING, "^2%s^7 unpaused the game\n", cl->name );
SV_TogglePause( message ); SV_TogglePause( message );
}
return true;
}
/* /*
================= =================
@ -1713,7 +1710,8 @@ void SV_UserinfoChanged( sv_client_t *cl, const char *userinfo )
sv_client_t *current; sv_client_t *current;
char *val; char *val;
if( !userinfo || !userinfo[0] ) return; // ignored if( !COM_CheckString( userinfo ))
return;
val = Info_ValueForKey( cl->userinfo, "name" ); val = Info_ValueForKey( cl->userinfo, "name" );
Q_strncpy( name2, val, sizeof( name2 )); Q_strncpy( name2, val, sizeof( name2 ));
@ -1812,12 +1810,13 @@ void SV_UserinfoChanged( sv_client_t *cl, const char *userinfo )
SV_UpdateUserinfo_f 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 )); Q_strncpy( cl->userinfo, Cmd_Argv( 1 ), sizeof( cl->userinfo ));
if( cl->state >= cs_connected ) if( cl->state >= cs_connected )
SetBits( cl->flags, FCL_RESEND_USERINFO ); // needs for update client info 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 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 ); Info_SetValueForKey( cl->userinfo, Cmd_Argv( 1 ), Cmd_Argv( 2 ), MAX_INFO_STRING );
if( cl->state >= cs_connected ) if( cl->state >= cs_connected )
SetBits( cl->flags, FCL_RESEND_USERINFO ); // needs for update client info 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 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; edict_t *pEntity = cl->edict;
if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background ) if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background )
return; return true;
if( pEntity->v.movetype != MOVETYPE_NOCLIP ) 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" ); SV_ClientPrintf( cl, "noclip OFF\n" );
pEntity->v.movetype = MOVETYPE_WALK; pEntity->v.movetype = MOVETYPE_WALK;
} }
}
/* return true;
==================
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;
}
} }
/* /*
@ -1886,18 +1864,20 @@ static void SV_Fly_f( sv_client_t *cl )
SV_Godmode_f 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; edict_t *pEntity = cl->edict;
if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background ) if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background )
return; return true;
pEntity->v.flags = pEntity->v.flags ^ FL_GODMODE; pEntity->v.flags = pEntity->v.flags ^ FL_GODMODE;
if( !FBitSet( pEntity->v.flags, FL_GODMODE )) if( !FBitSet( pEntity->v.flags, FL_GODMODE ))
SV_ClientPrintf( cl, "godmode OFF\n" ); SV_ClientPrintf( cl, "godmode OFF\n" );
else SV_ClientPrintf( cl, "godmode ON\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 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; edict_t *pEntity = cl->edict;
if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background ) if( !Cvar_VariableInteger( "sv_cheats" ) || sv.background )
return; return true;
pEntity->v.flags = pEntity->v.flags ^ FL_NOTARGET; pEntity->v.flags = pEntity->v.flags ^ FL_NOTARGET;
if( !FBitSet( pEntity->v.flags, FL_NOTARGET )) if( !FBitSet( pEntity->v.flags, FL_NOTARGET ))
SV_ClientPrintf( cl, "notarget OFF\n" ); SV_ClientPrintf( cl, "notarget OFF\n" );
else SV_ClientPrintf( cl, "notarget ON\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 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]; byte buffer[MAX_INIT_MSG];
sizebuf_t msg; sizebuf_t msg;
if( cl->state != cs_connected ) if( cl->state != cs_connected )
{ return false;
MsgDev( D_INFO, "'sendres' is not valid from the console\n" );
return;
}
MSG_Init( &msg, "SendResources", buffer, sizeof( buffer )); MSG_Init( &msg, "SendResources", buffer, sizeof( buffer ));
if( svs.maxclients > 1 && FBitSet( cl->flags, FCL_SEND_RESOURCES )) if( svs.maxclients > 1 && FBitSet( cl->flags, FCL_SEND_RESOURCES ))
return; return true;
SetBits( cl->flags, FCL_SEND_RESOURCES ); SetBits( cl->flags, FCL_SEND_RESOURCES );
SV_SendResources( cl, &msg ); SV_SendResources( cl, &msg );
Netchan_CreateFragments( &cl->netchan, &msg ); Netchan_CreateFragments( &cl->netchan, &msg );
Netchan_FragSend( &cl->netchan ); Netchan_FragSend( &cl->netchan );
return true;
} }
/* /*
@ -1952,23 +1933,22 @@ void SV_SendRes_f( sv_client_t *cl )
SV_DownloadFile_f SV_DownloadFile_f
================== ==================
*/ */
void SV_DownloadFile_f( sv_client_t *cl ) static qboolean SV_DownloadFile_f( sv_client_t *cl )
{ {
char *name; char *name;
char szModuleC[20] = "!ModuleC.dll";
if( Cmd_Argc() < 2 ) if( Cmd_Argc() < 2 )
return; return true;
name = Cmd_Argv( 1 ); name = Cmd_Argv( 1 );
if( !name || !name[0] ) if( !COM_CheckString( name ))
return; return true;
if( !COM_IsSafeFileToDownload( name ) || !sv_allow_download.value ) if( !COM_IsSafeFileToDownload( name ) || !sv_allow_download.value )
{ {
SV_FailDownload( cl, name ); SV_FailDownload( cl, name );
return; return true;
} }
if( cl->state == cs_spawned ) if( cl->state == cs_spawned )
@ -1976,7 +1956,7 @@ void SV_DownloadFile_f( sv_client_t *cl )
if( name[0] != '!' ) if( name[0] != '!' )
{ {
SV_FailDownload( cl, name ); SV_FailDownload( cl, name );
return; return true;
} }
} }
else else
@ -1988,12 +1968,12 @@ void SV_DownloadFile_f( sv_client_t *cl )
if( Netchan_CreateFileFragments( &cl->netchan, name )) if( Netchan_CreateFileFragments( &cl->netchan, name ))
{ {
Netchan_FragSend( &cl->netchan ); Netchan_FragSend( &cl->netchan );
return; return true;
} }
} }
SV_FailDownload( cl, name ); SV_FailDownload( cl, name );
return; return true;
} }
} }
@ -2024,6 +2004,8 @@ void SV_DownloadFile_f( sv_client_t *cl )
{ {
SV_FailDownload( cl, name ); SV_FailDownload( cl, name );
} }
return true;
} }
/* /*
@ -2031,20 +2013,16 @@ void SV_DownloadFile_f( sv_client_t *cl )
SV_Spawn_f 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 ) if( cl->state != cs_connected )
{ return false;
MsgDev( D_INFO, "'spawn' is not valid from the console\n" );
return;
}
// handle the case of a level changing while a client was connecting // handle the case of a level changing while a client was connecting
if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount ) if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount )
{ {
Msg( "'spawn' from different level\n" );
SV_New_f( cl ); SV_New_f( cl );
return; return true;
} }
SV_PutClientInServer( cl ); SV_PutClientInServer( cl );
@ -2056,6 +2034,7 @@ void SV_Spawn_f( sv_client_t *cl )
MSG_WriteByte( &sv.reliable_datagram, sv.paused ); MSG_WriteByte( &sv.reliable_datagram, sv.paused );
SV_ClientPrintf( cl, "Server is paused.\n" ); SV_ClientPrintf( cl, "Server is paused.\n" );
} }
return true;
} }
/* /*
@ -2063,22 +2042,19 @@ void SV_Spawn_f( sv_client_t *cl )
SV_Begin_f 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 ) if( cl->state != cs_connected )
{ return false;
MsgDev( D_INFO, "'begin' is not valid from the console\n" );
return;
}
// now client is spawned // now client is spawned
cl->state = cs_spawned; cl->state = cs_spawned;
return true;
} }
ucmd_t ucmds[] = ucmd_t ucmds[] =
{ {
{ "new", SV_New_f }, { "new", SV_New_f },
{ "fly", SV_Fly_f },
{ "god", SV_Godmode_f }, { "god", SV_Godmode_f },
{ "begin", SV_Begin_f }, { "begin", SV_Begin_f },
{ "spawn", SV_Spawn_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 )) if( !Q_strcmp( Cmd_Argv( 0 ), u->name ))
{ {
MsgDev( D_NOTE, "ucmd->%s()\n", u->name ); if( !u->func( cl ))
if( u->func ) 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; break;
} }
} }

View File

@ -53,28 +53,27 @@ void SV_BroadcastPrintf( sv_client_t *ignore, char *fmt, ... )
sv_client_t *cl; sv_client_t *cl;
int i; int i;
if( sv.state == ss_dead )
return;
va_start( argptr, fmt ); va_start( argptr, fmt );
Q_vsprintf( string, fmt, argptr ); Q_vsprintf( string, fmt, argptr );
va_end( 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 )) for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
continue; {
if( FBitSet( cl->flags, FCL_FAKECLIENT ))
continue;
if( cl == ignore || cl->state != cs_spawned ) if( cl == ignore || cl->state != cs_spawned )
continue; continue;
MSG_BeginServerCmd( &cl->netchan.message, svc_print ); MSG_BeginServerCmd( &cl->netchan.message, svc_print );
MSG_WriteString( &cl->netchan.message, string ); MSG_WriteString( &cl->netchan.message, string );
}
} }
// echo to console
MsgDev( D_REPORT, string ); MsgDev( D_REPORT, string );
} }
@ -230,7 +229,7 @@ void SV_Map_f( void )
// hold mapname to other place // hold mapname to other place
Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname ));
FS_StripExtension( mapname ); COM_StripExtension( mapname );
if( !SV_ValidateMap( mapname, true )) if( !SV_ValidateMap( mapname, true ))
return; return;
@ -264,7 +263,7 @@ void SV_MapBackground_f( void )
// hold mapname to other place // hold mapname to other place
Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname )); Q_strncpy( mapname, Cmd_Argv( 1 ), sizeof( mapname ));
FS_StripExtension( mapname ); COM_StripExtension( mapname );
if( !SV_ValidateMap( mapname, false )) if( !SV_ValidateMap( mapname, false ))
return; return;
@ -417,105 +416,6 @@ void SV_AutoSave_f( void )
SV_SaveGame( "autosave" ); 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 <map> [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 SV_Restart_f
@ -817,12 +717,7 @@ Kick everyone off, possibly in preparation for a new game
*/ */
void SV_KillServer_f( void ) void SV_KillServer_f( void )
{ {
if( !svs.initialized ) Host_ShutdownServer();
return;
Q_strncpy( host.finalmsg, "Server was killed", MAX_STRING );
SV_Shutdown( false );
NET_Config ( false ); // close network sockets
} }
/* /*
@ -917,7 +812,6 @@ is available always
void SV_InitHostCommands( void ) void SV_InitHostCommands( void )
{ {
Cmd_AddCommand( "map", SV_Map_f, "start new level" ); Cmd_AddCommand( "map", SV_Map_f, "start new level" );
Cmd_AddCommand( "changelevel", SV_ChangeLevel_f, "changing level" );
if( host.type == HOST_NORMAL ) if( host.type == HOST_NORMAL )
{ {

View File

@ -602,7 +602,6 @@ void SV_WriteEntitiesToClient( sv_client_t *cl, sizebuf_t *msg )
memset( frame_ents.sended, 0, sizeof( frame_ents.sended )); memset( frame_ents.sended, 0, sizeof( frame_ents.sended ));
ClearBits( sv.hostflags, SVF_MERGE_VISIBILITY ); ClearBits( sv.hostflags, SVF_MERGE_VISIBILITY );
sv.net_framenum++; // now all portal-through entities are invalidate
// clear everything in this snapshot // clear everything in this snapshot
frame_ents.num_entities = c_fullsend = c_notsend = 0; frame_ents.num_entities = c_fullsend = c_notsend = 0;

View File

@ -863,7 +863,7 @@ edict_t *SV_AllocEdict( void )
LINK_ENTITY_FUNC SV_GetEntityClass( const char *pszClassName ) LINK_ENTITY_FUNC SV_GetEntityClass( const char *pszClassName )
{ {
// allocate edict private memory (passed by dlls) // 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 ) 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; static uint last_spawncount = 0;
char mapname[MAX_QPATH];
char *spawn_entity;
if( !s1 || s1[0] <= ' ' || sv.background ) if( !COM_CheckString( level ) || sv.state != ss_active )
return; 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
// make sure we don't issue two changelevels // make sure we don't issue two changelevels
if( svs.spawncount == last_spawncount ) if( svs.spawncount == last_spawncount )
return; return;
last_spawncount = svs.spawncount; 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 (); SV_SkipUpdates ();
if( !s2 ) Cbuf_AddText( va( "changelevel %s\n", s1 )); // Quake changlevel // changelevel will be executed on a next frame
else Cbuf_AddText( va( "changelevel %s %s\n", s1, s2 )); // Half-Life changelevel 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 ) if( level == at_warning )
{ {
Sys_Print( va( "^3Warning:^7 %s", buffer )); Con_Printf( "^3Warning:^7 %s", buffer );
} }
else if( level == at_error ) else if( level == at_error )
{ {
Sys_Print( va( "^1Error:^7 %s", buffer )); Con_Printf( "^1Error:^7 %s", buffer );
} }
else if( level == at_logged ) else if( level == at_logged )
{ {
@ -2826,7 +2888,7 @@ static void pfnAlertMessage( ALERT_TYPE level, char *szFmt, ... )
} }
else else
{ {
Sys_Print( buffer ); Con_Printf( buffer );
} }
} }
@ -2994,7 +3056,7 @@ pfnPEntityOfEntOffset
*/ */
edict_t* pfnPEntityOfEntOffset( int iEntOffset ) 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; int number;
if( !pEdict ) return 0; // world ?
number = NUM_FOR_EDICT( pEdict ); number = NUM_FOR_EDICT( pEdict );
if( number < 0 || number >= svgame.numEntities ) if( number < 0 || number > GI->max_edicts )
return 0; // out of range Host_Error( "bad entity number %d\n", number );
return number; return number;
} }
@ -3032,41 +3096,47 @@ pfnPEntityOfEntIndex
*/ */
edict_t* pfnPEntityOfEntIndex( int iEntIndex ) edict_t* pfnPEntityOfEntIndex( int iEntIndex )
{ {
if( iEntIndex < 0 || iEntIndex >= svgame.numEntities ) if( iEntIndex >= 0 && iEntIndex < GI->max_edicts )
return NULL; // out of range {
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 pfnFindEntityByVars
debug routine debug thing
============= =============
*/ */
edict_t* pfnFindEntityByVars( entvars_t *pvars ) edict_t* pfnFindEntityByVars( entvars_t *pvars )
{ {
edict_t *e; edict_t *pEdict;
int i; int i;
// don't pass invalid arguments // don't pass invalid arguments
if( !pvars ) return NULL; if( !pvars ) return NULL;
for( i = 0; i < svgame.numEntities; i++ ) for( i = 0; i < GI->max_edicts; i++ )
{ {
e = EDICT_NUM( i ); pEdict = EDICT_NUM( i );
// g-cont: we should compare pointers
if( &e->v == pvars ) if( &pEdict->v == pvars )
{ return pEdict; // found it
if( e->v.pContainingEntity != e )
{
MsgDev( D_NOTE, "fixing pContainingEntity for %s\n", SV_ClassName( e ));
e->v.pContainingEntity = e;
}
return e; // found it
}
} }
return NULL; return NULL;
} }
@ -3200,7 +3270,7 @@ pfnFunctionFromName
*/ */
dword pfnFunctionFromName( const char *pName ) 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 ) 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.movevars.fog_settings = 0;
svgame.globals->maxEntities = GI->max_edicts; svgame.globals->maxEntities = GI->max_edicts;
svgame.globals->maxClients = svs.maxclients;
svgame.globals->mapname = MAKE_STRING( sv.name ); svgame.globals->mapname = MAKE_STRING( sv.name );
svgame.globals->startspot = MAKE_STRING( sv.startspot ); svgame.globals->startspot = MAKE_STRING( sv.startspot );
svgame.globals->time = sv.time; svgame.globals->time = sv.time;
@ -4782,6 +4851,9 @@ void SV_SpawnEntities( const char *mapname, char *entities )
void SV_UnloadProgs( void ) void SV_UnloadProgs( void )
{ {
if( !svgame.hInstance )
return;
SV_DeactivateServer (); SV_DeactivateServer ();
Delta_Shutdown (); Delta_Shutdown ();
Mod_ClearUserData (); Mod_ClearUserData ();
@ -4795,6 +4867,10 @@ void SV_UnloadProgs( void )
Cvar_FullSet( "host_gameloaded", "0", FCVAR_READ_ONLY ); Cvar_FullSet( "host_gameloaded", "0", FCVAR_READ_ONLY );
Cvar_FullSet( "sv_background", "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 // remove server cmds
SV_KillOperatorCommands(); SV_KillOperatorCommands();
@ -4805,7 +4881,7 @@ void SV_UnloadProgs( void )
Mod_ResetStudioAPI (); Mod_ResetStudioAPI ();
Com_FreeLibrary( svgame.hInstance ); COM_FreeLibrary( svgame.hInstance );
Mem_FreePool( &svgame.mempool ); Mem_FreePool( &svgame.mempool );
memset( &svgame, 0, sizeof( svgame )); memset( &svgame, 0, sizeof( svgame ));
} }
@ -4828,7 +4904,7 @@ qboolean SV_LoadProgs( const char *name )
svgame.pmove = &gpMove; svgame.pmove = &gpMove;
svgame.globals = &gpGlobals; svgame.globals = &gpGlobals;
svgame.mempool = Mem_AllocPool( "Server Edicts Zone" ); svgame.mempool = Mem_AllocPool( "Server Edicts Zone" );
svgame.hInstance = Com_LoadLibrary( name, true ); svgame.hInstance = COM_LoadLibrary( name, true );
if( !svgame.hInstance ) return false; if( !svgame.hInstance ) return false;
// make sure what new dll functions is cleared // 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 // make local copy of engfuncs to prevent overwrite it with bots.dll
memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs )); memcpy( &gpEngfuncs, &gEngfuncs, sizeof( gpEngfuncs ));
GetEntityAPI = (APIFUNCTION)Com_GetProcAddress( svgame.hInstance, "GetEntityAPI" ); GetEntityAPI = (APIFUNCTION)COM_GetProcAddress( svgame.hInstance, "GetEntityAPI" );
GetEntityAPI2 = (APIFUNCTION2)Com_GetProcAddress( svgame.hInstance, "GetEntityAPI2" ); GetEntityAPI2 = (APIFUNCTION2)COM_GetProcAddress( svgame.hInstance, "GetEntityAPI2" );
GiveNewDllFuncs = (NEW_DLL_FUNCTIONS_FN)Com_GetProcAddress( svgame.hInstance, "GetNewDLLFunctions" ); GiveNewDllFuncs = (NEW_DLL_FUNCTIONS_FN)COM_GetProcAddress( svgame.hInstance, "GetNewDLLFunctions" );
if( !GetEntityAPI && !GetEntityAPI2 ) if( !GetEntityAPI && !GetEntityAPI2 )
{ {
Com_FreeLibrary( svgame.hInstance ); COM_FreeLibrary( svgame.hInstance );
MsgDev( D_NOTE, "SV_LoadProgs: failed to get address of GetEntityAPI proc\n" ); MsgDev( D_NOTE, "SV_LoadProgs: failed to get address of GetEntityAPI proc\n" );
svgame.hInstance = NULL; svgame.hInstance = NULL;
return false; return false;
} }
GiveFnptrsToDll = (GIVEFNPTRSTODLL)Com_GetProcAddress( svgame.hInstance, "GiveFnptrsToDll" ); GiveFnptrsToDll = (GIVEFNPTRSTODLL)COM_GetProcAddress( svgame.hInstance, "GiveFnptrsToDll" );
if( !GiveFnptrsToDll ) if( !GiveFnptrsToDll )
{ {
Com_FreeLibrary( svgame.hInstance ); COM_FreeLibrary( svgame.hInstance );
MsgDev( D_NOTE, "SV_LoadProgs: failed to get address of GiveFnptrsToDll proc\n" ); MsgDev( D_NOTE, "SV_LoadProgs: failed to get address of GiveFnptrsToDll proc\n" );
svgame.hInstance = NULL; svgame.hInstance = NULL;
return false; return false;
@ -4888,7 +4964,7 @@ qboolean SV_LoadProgs( const char *name )
// fallback to old API // fallback to old API
if( !GetEntityAPI( &svgame.dllFuncs, version )) if( !GetEntityAPI( &svgame.dllFuncs, version ))
{ {
Com_FreeLibrary( svgame.hInstance ); COM_FreeLibrary( svgame.hInstance );
MsgDev( D_ERROR, "SV_LoadProgs: couldn't get entity API\n" ); MsgDev( D_ERROR, "SV_LoadProgs: couldn't get entity API\n" );
svgame.hInstance = NULL; svgame.hInstance = NULL;
return false; return false;
@ -4898,7 +4974,7 @@ qboolean SV_LoadProgs( const char *name )
} }
else if( !GetEntityAPI( &svgame.dllFuncs, version )) 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" ); MsgDev( D_ERROR, "SV_LoadProgs: couldn't get entity API\n" );
svgame.hInstance = NULL; svgame.hInstance = NULL;
return false; return false;
@ -4921,6 +4997,7 @@ qboolean SV_LoadProgs( const char *name )
svgame.globals->maxEntities = GI->max_edicts; svgame.globals->maxEntities = GI->max_edicts;
svgame.globals->maxClients = svs.maxclients; svgame.globals->maxClients = svs.maxclients;
svgame.edicts = Mem_Alloc( svgame.mempool, sizeof( edict_t ) * GI->max_edicts ); 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 svgame.numEntities = svs.maxclients + 1; // clients + world
for( i = 0, e = svgame.edicts; i < GI->max_edicts; i++, e++ ) for( i = 0, e = svgame.edicts; i < GI->max_edicts; i++, e++ )

View File

@ -238,8 +238,8 @@ void SV_CreateGenericResources( void )
string filename, token; string filename, token;
Q_strncpy( filename, sv.model_precache[1], sizeof( filename )); Q_strncpy( filename, sv.model_precache[1], sizeof( filename ));
FS_StripExtension( filename ); COM_StripExtension( filename );
FS_DefaultExtension( filename, ".res" ); COM_DefaultExtension( filename, ".res" );
COM_FixSlashes( filename ); COM_FixSlashes( filename );
afile = FS_LoadFile( filename, NULL, false ); afile = FS_LoadFile( filename, NULL, false );
@ -344,8 +344,8 @@ char *SV_EntityScript( void )
// check for entfile too // check for entfile too
Q_strncpy( entfilename, sv.worldmodel->name, sizeof( entfilename )); Q_strncpy( entfilename, sv.worldmodel->name, sizeof( entfilename ));
FS_StripExtension( entfilename ); COM_StripExtension( entfilename );
FS_DefaultExtension( entfilename, ".ent" ); COM_DefaultExtension( entfilename, ".ent" );
// make sure what entity patch is never than bsp // make sure what entity patch is never than bsp
ft1 = FS_FileTime( sv.worldmodel->name, false ); ft1 = FS_FileTime( sv.worldmodel->name, false );
@ -576,13 +576,8 @@ void SV_ActivateServer( int runPhysics )
// tell what kind of server has been started. // tell what kind of server has been started.
if( svs.maxclients > 1 ) if( svs.maxclients > 1 )
{ Con_Printf( "%i player server started\n", svs.maxclients );
MsgDev( D_INFO, "%i player server started\n", svs.maxclients ); else Con_Printf( "Game started\n" );
}
else
{
MsgDev( D_INFO, "Game started\n" );
}
Log_Printf( "Started map \"%s\" (CRC \"%i\")\n", sv.name, sv.worldmapCRC ); Log_Printf( "Started map \"%s\" (CRC \"%i\")\n", sv.name, sv.worldmapCRC );
@ -591,20 +586,18 @@ void SV_ActivateServer( int runPhysics )
Mod_FreeUnused (); Mod_FreeUnused ();
host.movevars_changed = true; host.movevars_changed = true;
Host_SetServerState( sv.state );
MsgDev( D_INFO, "level loaded at %.2f sec\n", Sys_DoubleTime() - svs.timestart ); MsgDev( D_INFO, "level loaded at %.2f sec\n", Sys_DoubleTime() - svs.timestart );
if( svs.maxclients > 1 ) if( svs.maxclients > 1 )
{ {
char *mapchangecfgfile = Cvar_VariableString( "mapchangecfgfile" ); char *cycle = Cvar_VariableString( "mapchangecfgfile" );
if( *mapchangecfgfile ) Cbuf_AddText( va( "exec %s\n", mapchangecfgfile ));
if( COM_CheckString( cycle ))
Cbuf_AddText( va( "exec %s\n", cycle ));
if( public_server->value ) if( public_server->value )
{
MsgDev( D_INFO, "Adding your server to master server list\n" );
Master_Add( ); Master_Add( );
}
} }
} }
@ -666,8 +659,6 @@ qboolean SV_InitGame( void )
return false; // failed to loading server.dll 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 // client frames will be allocated in SV_ClientConnect
svs.initialized = true; svs.initialized = true;
@ -731,24 +722,13 @@ void SV_SetupClients( void )
// check if clients count was really changed // check if clients count was really changed
if( svs.maxclients != (int)sv_maxclients->value ) if( svs.maxclients != (int)sv_maxclients->value )
changed_maxclients = true; changed_maxclients = true;
svs.maxclients = sv_maxclients->value; // copy the actual value from cvar 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( !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 // dedicated servers are can't be single player and are usually DM
if( host.type == HOST_DEDICATED ) if( host.type == HOST_DEDICATED )
svs.maxclients = bound( 4, svs.maxclients, MAX_CLIENTS ); svs.maxclients = bound( 4, svs.maxclients, MAX_CLIENTS );
@ -764,7 +744,6 @@ void SV_SetupClients( void )
// feedback for cvar // feedback for cvar
Cvar_FullSet( "maxplayers", va( "%d", svs.maxclients ), FCVAR_LATCH ); Cvar_FullSet( "maxplayers", va( "%d", svs.maxclients ), FCVAR_LATCH );
SV_UPDATE_BACKUP = ( svs.maxclients == 1 ) ? SINGLEPLAYER_BACKUP : MULTIPLAYER_BACKUP; 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.clients = Z_Realloc( svs.clients, sizeof( sv_client_t ) * svs.maxclients );
svs.num_client_entities = svs.maxclients * SV_UPDATE_BACKUP * NUM_PACKET_ENTITIES; svs.num_client_entities = svs.maxclients * SV_UPDATE_BACKUP * NUM_PACKET_ENTITIES;
@ -773,15 +752,8 @@ void SV_SetupClients( void )
// init network stuff // init network stuff
NET_Config(( svs.maxclients > 1 )); 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 svgame.numEntities = svs.maxclients + 1; // clients + world
ClearBits( sv_maxclients->flags, FCVAR_CHANGED ); 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; int i, current_skill;
edict_t *ent; edict_t *ent;
SV_SetupClients();
SV_AllocClientFrames();
if( !SV_InitGame( )) if( !SV_InitGame( ))
return false; 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_Printf( "Loading map \"%s\"\n", mapname );
Log_PrintServerVars(); Log_PrintServerVars();
SV_SetupClients();
SV_AllocClientFrames();
svs.timestart = Sys_DoubleTime(); svs.timestart = Sys_DoubleTime();
svs.spawncount++; // any partially connected client will be restarted 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 ); 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 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.time = svgame.globals->time = 1.0f; // server spawn time it's always 1.0 second
sv.background = background; 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 ); current_skill = bound( 0, current_skill, 3 );
Cvar_SetValue( "skill", (float)current_skill ); 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 ) if( sv.background )
{ {
// tell the game parts about background state // 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 ); 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 // 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 ) if( startspot )
Q_strncpy( sv.startspot, startspot, sizeof( sv.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 ); 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 ); 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++ ) for( i = WORLD_INDEX; i < sv.worldmodel->numsubmodels; i++ )
{ {
Q_sprintf( sv.model_precache[i+1], "*%i", 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 // heartbeats will always be sent to the id master
svs.last_heartbeat = MAX_HEARTBEAT; // send immediately 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 // get actual movevars
SV_UpdateMovevars( true ); SV_UpdateMovevars( true );

View File

@ -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 ) if( svs.maxclients <= 1 )
return; return false;
if( Cmd_Argc() != 2 ) if( Cmd_Argc() != 2 )
{ {
@ -171,7 +171,7 @@ void SV_ServerLog_f( sv_client_t *cl )
if( svs.log.active ) if( svs.log.active )
SV_ClientPrintf( cl, "currently logging\n" ); SV_ClientPrintf( cl, "currently logging\n" );
else SV_ClientPrintf( cl, "not currently logging\n" ); else SV_ClientPrintf( cl, "not currently logging\n" );
return; return true;
} }
if( !Q_stricmp( Cmd_Argv( 1 ), "off" )) 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 )); SV_ClientPrintf( cl, "log: unknown parameter %s\n", Cmd_Argv( 1 ));
} }
return true;
} }

View File

@ -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( 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( logsdir, "logs", 0, "place to store multiplayer logs" );
CVAR_DEFINE_AUTO( bannedcfgfile, "banned.cfg", 0, "name of list of banned users" ); 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( deathmatch, "0", 0, "deathmatch mode in multiplayer game" );
CVAR_DEFINE_AUTO( coop, "0", FCVAR_LATCH, "cooperative 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( teamplay, "0", 0, "team mode in multiplayer game" );
CVAR_DEFINE_AUTO( skill, "1", 0, "skill level in singleplayer 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" ); 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. 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; sv_client_t *cl;
byte msg_buf[1024];
sizebuf_t msg; sizebuf_t msg;
int i; int i;
@ -827,18 +827,8 @@ void SV_FinalMessage( char *message, qboolean reconnect )
MSG_BeginServerCmd( &msg, svc_print ); MSG_BeginServerCmd( &msg, svc_print );
MSG_WriteString( &msg, va( "%s\n", message )); MSG_WriteString( &msg, va( "%s\n", message ));
if( reconnect ) if( reconnect ) SV_BuildReconnect( &msg );
{ else MSG_BeginServerCmd( &msg, svc_disconnect );
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 );
}
// send it twice // send it twice
// stagger the packets to crutch operating system limited buffers // stagger the packets to crutch operating system limited buffers
@ -882,7 +872,7 @@ Called when each game quits,
before Sys_Quit or Sys_Error before Sys_Quit or Sys_Error
================ ================
*/ */
void SV_Shutdown( qboolean reconnect ) void SV_Shutdown( const char *finalmsg )
{ {
// already freed // already freed
if( !SV_Initialized( )) return; if( !SV_Initialized( )) return;
@ -890,32 +880,22 @@ void SV_Shutdown( qboolean reconnect )
// rcon will be disconnected // rcon will be disconnected
SV_EndRedirect(); SV_EndRedirect();
if( host.type == HOST_DEDICATED )
MsgDev( D_INFO, "SV_Shutdown: %s\n", host.finalmsg );
if( svs.clients ) if( svs.clients )
SV_FinalMessage( host.finalmsg, reconnect ); SV_FinalMessage( finalmsg, false );
if( public_server->value && svs.maxclients != 1 ) if( public_server->value && svs.maxclients != 1 )
Master_Shutdown(); Master_Shutdown();
if( !reconnect ) SV_UnloadProgs (); NET_Config( false );
else SV_DeactivateServer (); SV_UnloadProgs ();
// free current level // free current level
memset( &sv, 0, sizeof( sv )); memset( &sv, 0, sizeof( sv ));
Host_SetServerState( ss_dead );
SV_FreeClients(); SV_FreeClients();
Log_Printf( "Server shutdown\n" ); Log_Printf( "Server shutdown\n" );
Log_Close(); Log_Close();
if( svs.baselines )
{
Z_Free( svs.baselines );
svs.baselines = NULL;
}
svs.initialized = false; svs.initialized = false;
} }

View File

@ -1815,6 +1815,9 @@ void SV_Physics( void )
// animate lightstyles (used for GetEntityIllum) // animate lightstyles (used for GetEntityIllum)
SV_RunLightStyles (); SV_RunLightStyles ();
// increase framecount
sv.framecount++;
if( sv_skyspeed.value ) if( sv_skyspeed.value )
{ {
// evaluate sky rotation. // evaluate sky rotation.
@ -2057,7 +2060,7 @@ qboolean SV_InitPhysicsAPI( void )
{ {
static PHYSICAPI pPhysIface; static PHYSICAPI pPhysIface;
pPhysIface = (PHYSICAPI)Com_GetProcAddress( svgame.hInstance, "Server_GetPhysicsInterface" ); pPhysIface = (PHYSICAPI)COM_GetProcAddress( svgame.hInstance, "Server_GetPhysicsInterface" );
if( pPhysIface ) if( pPhysIface )
{ {
if( pPhysIface( SV_PHYSICS_INTERFACE_VERSION, &gPhysicsAPI, &svgame.physFuncs )) if( pPhysIface( SV_PHYSICS_INTERFACE_VERSION, &gPhysicsAPI, &svgame.physFuncs ))

View File

@ -171,7 +171,7 @@ int SumBytes( SaveFileSectionsInfo_t *section )
void SV_InitSaveRestore( void ) 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 ); pCopy = FS_Open( t->filenames[i], "rb", true );
// filename can only be as long as a map name + extension // 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, szName, SAVENAME_LENGTH );
FS_Write( pFile, &fileSize, sizeof( int )); FS_Write( pFile, &fileSize, sizeof( int ));
FS_FileCopy( pFile, pCopy, fileSize ); FS_FileCopy( pFile, pCopy, fileSize );
@ -1960,6 +1960,7 @@ void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char
pSaveData = SV_SaveGameState( true ); pSaveData = SV_SaveGameState( true );
} }
SV_InactivateClients ();
SV_DeactivateServer (); SV_DeactivateServer ();
if( !SV_SpawnServer( level, startspot, false )) if( !SV_SpawnServer( level, startspot, false ))
@ -1982,6 +1983,7 @@ void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char
else else
{ {
// classic quake changelevel // classic quake changelevel
svgame.dllFuncs.pfnResetGlobalState();
SV_SpawnEntities( level, SV_EntityScript( )); SV_SpawnEntities( level, SV_EntityScript( ));
SV_ActivateServer( true ); SV_ActivateServer( true );
} }