05 Mar 2018

This commit is contained in:
g-cont 2018-03-05 00:00:00 +03:00 committed by Alibek Omarov
parent 4f82f5249d
commit f9c1a60dfd
32 changed files with 318 additions and 257 deletions

View File

@ -261,6 +261,8 @@ typedef struct render_interface_s
byte* (*Mod_GetCurrentVis)( void );
// tell the renderer what new map is started
void (*R_NewMap)( void );
// clear the render entities before each frame
void (*R_ClearScene)( void );
} render_interface_t;
#endif//RENDER_API_H

View File

@ -447,9 +447,6 @@ void CL_StopRecord( void )
CL_WriteDemoCmdHeader( dem_stop, cls.demofile );
stoptime = CL_GetDemoRecordClock();
// close down the hud for now.
// g-cont. is this need???
if( clgame.hInstance ) clgame.dllFuncs.pfnReset();
curpos = FS_Tell( cls.demofile );

View File

@ -906,9 +906,12 @@ qboolean CL_AddVisibleEntity( cl_entity_t *ent, int entityType )
return false;
}
// don't add the player in firstperson mode
if( RP_LOCALCLIENT( ent ) && !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
return false;
if( FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
{
// don't add the player in firstperson mode
if( RP_LOCALCLIENT( ent ) && !CL_IsThirdPerson( ) && ( ent->index == cl.viewentity ))
return false;
}
if( entityType == ET_BEAM )
{
@ -987,6 +990,13 @@ void CL_LinkPlayers( frame_t *frame )
if( state->messagenum != cl.parsecount )
continue; // not present this frame
if( !FBitSet( host.features, ENGINE_COMPUTE_STUDIO_LERP ))
{
// don't add the player in firstperson mode
if( !CL_IsThirdPerson( ) && ( i == cl.viewentity - 1 ))
continue;
}
if( !state->modelindex || FBitSet( state->effects, EF_NODRAW ))
continue;
@ -1196,6 +1206,22 @@ void CL_LinkPacketEntities( frame_t *frame )
}
}
/*
===============
CL_MoveThirdpersonCamera
think thirdperson
===============
*/
void CL_MoveThirdpersonCamera( void )
{
if( cls.state == ca_disconnected || cls.state == ca_cinematic )
return;
// think thirdperson camera
clgame.dllFuncs.CAM_Think ();
}
/*
===============
CL_EmitEntities
@ -1224,8 +1250,9 @@ void CL_EmitEntities( void )
// set client ideal pitch when mlook is disabled
CL_SetIdealPitch ();
// think thirdperson camera
clgame.dllFuncs.CAM_Think ();
// clear the scene befor start new frame
if( clgame.drawFuncs.R_ClearScene != NULL )
clgame.drawFuncs.R_ClearScene();
// link all the visible clients first
CL_LinkPlayers ( &cl.frames[cl.parsecountmod] );

View File

@ -192,12 +192,12 @@ An svc_signonnum has been received, perform a client side setup
*/
void CL_SignonReply( void )
{
Con_Printf( "CL_SignonReply: %i\n", cls.signon );
// g-cont. my favorite message :-)
Con_DPrintf( "CL_SignonReply: %i\n", cls.signon );
switch( cls.signon )
{
case 1:
// g-cont. my favorite message :-)
CL_ServerCommand( true, "begin" );
if( host_developer.value >= DEV_EXTENDED )
Mem_PrintStats();
@ -604,7 +604,7 @@ void CL_CreateCmd( void )
CL_ApplyAddAngle();
}
active = ( cls.state == ca_active && !cl.paused && !cls.demoplayback );
active = (( cls.signon == SIGNONS ) && !cl.paused && !cls.demoplayback );
clgame.dllFuncs.CL_CreateMove( host.frametime, &pcmd->cmd, active );
CL_PopPMStates();
@ -2323,7 +2323,6 @@ void CL_InitLocal( void )
// these two added to shut up CS 1.5 about 'unknown' commands
Cvar_Get( "lightgamma", "1", FCVAR_ARCHIVE, "ambient lighting level (legacy, unused)" );
Cvar_Get( "direct", "1", FCVAR_ARCHIVE, "direct lighting level (legacy, unused)" );
Cvar_Get( "voice_serverdebug", "0", 0, "debug voice (legacy, unused)" );
// server commands
Cmd_AddCommand ("noclip", NULL, "enable or disable no clipping mode" );
@ -2472,6 +2471,7 @@ void Host_ClientFrame( void )
// a new portion updates from server
CL_RedoPrediction ();
// TODO: implement
// Voice_Idle( host.frametime );
// emit visible entities
@ -2480,9 +2480,11 @@ void Host_ClientFrame( void )
// in case we lost connection
CL_CheckForResend ();
// while( CL_RequestMissingResources( ));
// procssing resources on handle
while( CL_RequestMissingResources( ));
// CL_HTTPUpdate ();
// handle thirdperson camera
CL_MoveThirdpersonCamera();
// handle spectator movement
CL_MoveSpectatorCamera();

View File

@ -33,7 +33,7 @@ const char *svc_strings[svc_lastmsg+1] =
"svc_nop",
"svc_disconnect",
"svc_event",
"svc_version",
"svc_changing",
"svc_setview",
"svc_sound",
"svc_time",
@ -642,6 +642,34 @@ void CL_ParseSoundFade( sizebuf_t *msg )
S_FadeClientVolume( fadePercent, fadeOutSeconds, holdTime, fadeInSeconds );
}
/*
==================
CL_RequestMissingResources
==================
*/
qboolean CL_RequestMissingResources( void )
{
resource_t *p;
if( !cls.dl.doneregistering && ( cls.dl.custom || cls.state == ca_validate ))
{
p = cl.resourcesneeded.pNext;
if( p == &cl.resourcesneeded )
{
cls.dl.doneregistering = true;
cls.dl.custom = false;
}
else if( !FBitSet( p->ucFlags, RES_WASMISSING ))
{
CL_MoveToOnHandList( cl.resourcesneeded.pNext );
return true;
}
}
return false;
}
/*
==================
CL_ParseCustomization
@ -732,18 +760,20 @@ CL_ParseServerData
*/
void CL_ParseServerData( sizebuf_t *msg )
{
int i, servercount, checksum;
int playernum, maxclients;
char gamefolder[MAX_QPATH];
qboolean background;
int i;
MsgDev( D_NOTE, "Serverdata packet received.\n" );
cls.timestart = Sys_DoubleTime();
cls.demowaiting = false; // server is changed
cls.state = ca_connected;
clgame.load_sequence++; // now all hud sprites are invalid
cls.signon = 0; // reset signon state
// wipe the client_t struct
if( !cls.changelevel && !cls.changedemo )
CL_ClearState ();
cls.state = ca_connected;
// Re-init hud video, especially if we changed game directories
clgame.dllFuncs.pfnVidInit();
@ -754,49 +784,22 @@ void CL_ParseServerData( sizebuf_t *msg )
if( cls.serverProtocol != PROTOCOL_VERSION )
Host_Error( "Server use invalid protocol (%i should be %i)\n", cls.serverProtocol, PROTOCOL_VERSION );
servercount = MSG_ReadLong( msg );
checksum = MSG_ReadLong( msg );
playernum = MSG_ReadByte( msg );
maxclients = MSG_ReadByte( msg );
cl.servercount = MSG_ReadLong( msg );
cl.checksum = MSG_ReadLong( msg );
cl.playernum = MSG_ReadByte( msg );
cl.maxclients = MSG_ReadByte( msg );
clgame.maxEntities = MSG_ReadWord( msg );
clgame.maxEntities = bound( 600, clgame.maxEntities, MAX_EDICTS );
clgame.maxModels = MSG_ReadWord( msg );
Q_strncpy( clgame.mapname, MSG_ReadString( msg ), MAX_STRING );
Q_strncpy( clgame.maptitle, MSG_ReadString( msg ), MAX_STRING );
background = MSG_ReadOneBit( msg );
cls.changelevel = MSG_ReadOneBit( msg );
Q_strncpy( gamefolder, MSG_ReadString( msg ), MAX_STRING );
Q_strncpy( gamefolder, MSG_ReadString( msg ), MAX_QPATH );
host.features = (uint)MSG_ReadLong( msg );
if( clgame.maxModels > MAX_MODELS )
MsgDev( D_WARN, "server model limit is above client model limit %i > %i\n", clgame.maxModels, MAX_MODELS );
if( cls.changelevel && cls.demoplayback )
cls.changedemo = true;
// wipe the client_t struct
CL_ClearState ();
// allow console in multiplayer games
if( maxclients > 1 ) host.allow_console = true;
// fill the client struct
cl.servercount = servercount;
cl.checksum = checksum;
cl.playernum = playernum;
cl.maxclients = maxclients;
// set the background state
if( cls.demoplayback && ( cls.demonum != -1 ))
{
host.mouse_visible = false;
cl.background = true;
}
else cl.background = background;
if( cls.changedemo )
SCR_BeginLoadingPlaque( cl.background );
if( Con_FixedFont( ))
{
// seperate the printfs so the server message can have a color
@ -812,8 +815,11 @@ void CL_ParseServerData( sizebuf_t *msg )
}
// multiplayer game?
if( cl.maxclients != 1 )
if( cl.maxclients > 1 )
{
// allow console in multiplayer games
host.allow_console = true;
// loading user settings
CSCR_LoadDefaultCVars( "user.scr" );
@ -822,6 +828,15 @@ void CL_ParseServerData( sizebuf_t *msg )
}
else Cvar_Reset( "r_decals" );
// set the background state
if( cls.demoplayback && ( cls.demonum != -1 ))
{
// re-init mouse
host.mouse_visible = false;
cl.background = true;
}
else cl.background = background;
if( cl.background ) // tell the game parts about background state
Cvar_FullSet( "cl_background", "1", FCVAR_READ_ONLY );
else Cvar_FullSet( "cl_background", "0", FCVAR_READ_ONLY );
@ -841,7 +856,9 @@ void CL_ParseServerData( sizebuf_t *msg )
cl.viewentity = cl.playernum + 1;
gameui.globals->maxClients = cl.maxclients;
Q_strncpy( gameui.globals->maptitle, clgame.maptitle, sizeof( gameui.globals->maptitle ));
CL_InitEdicts (); // re-arrange edicts
if( !cls.changelevel && !cls.changedemo )
CL_InitEdicts (); // re-arrange edicts
// get splash name
if( cls.demoplayback && ( cls.demonum != -1 ))
@ -863,31 +880,6 @@ void CL_ParseServerData( sizebuf_t *msg )
#else
MSG_WriteString( &cls.netchan.message, va( "sendres %i\n", cl.servercount ));
#endif
if( scr_dark->value )
{
screenfade_t *sf = &clgame.fade;
client_textmessage_t *title;
title = CL_TextMessageGet( "GAMETITLE" );
if( title )
{
// get settings from titles.txt
sf->fadeEnd = title->holdtime + title->fadeout;
sf->fadeReset = title->fadeout;
}
else sf->fadeEnd = sf->fadeReset = 5.0f;
sf->fadeFlags = FFADE_IN;
sf->fader = sf->fadeg = sf->fadeb = 0;
sf->fadealpha = 255;
sf->fadeSpeed = (float)sf->fadealpha / sf->fadeReset;
sf->fadeReset += cl.time;
sf->fadeEnd += sf->fadeReset;
Cvar_SetValue( "v_dark", 0.0f );
}
// need to prep refresh at next oportunity
cl.video_prepped = false;
cl.audio_prepped = false;
@ -2276,10 +2268,37 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
CL_ParseEvent( msg );
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
break;
case svc_version:
param1 = MSG_ReadLong( msg );
if( param1 != PROTOCOL_VERSION )
Host_Error( "Server is protocol %i instead of %i\n", param1, PROTOCOL_VERSION );
case svc_changing:
if( MSG_ReadOneBit( msg ))
{
cls.changelevel = true;
S_StopAllSounds( true );
MsgDev( D_INFO, "Server changing, reconnecting\n" );
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
{
// g-cont. local client skip the challenge
if( SV_Active()) cls.state = ca_disconnected;
else cls.state = ca_connecting;
cls.connect_time = MAX_HEARTBEAT;
}
break;
case svc_setview:
CL_ParseViewEntity( msg );

View File

@ -27,7 +27,7 @@ convar_t *cl_testlights;
convar_t *cl_allow_levelshots;
convar_t *cl_levelshot_name;
convar_t *cl_envshot_size;
convar_t *scr_dark;
convar_t *v_dark;
typedef struct
{
@ -704,7 +704,7 @@ void SCR_Init( void )
scr_download = Cvar_Get( "scr_download", "0", 0, "downloading bar progress" );
cl_testlights = Cvar_Get( "cl_testlights", "0", 0, "test dynamic lights" );
cl_envshot_size = Cvar_Get( "cl_envshot_size", "256", FCVAR_ARCHIVE, "envshot size of cube side" );
scr_dark = Cvar_Get( "v_dark", "0", 0, "starts level from dark screen" );
v_dark = Cvar_Get( "v_dark", "0", 0, "starts level from dark screen" );
scr_viewsize = Cvar_Get( "viewsize", "120", FCVAR_ARCHIVE, "screen size" );
// register our commands

View File

@ -2867,14 +2867,14 @@ int CL_DecalIndexFromName( const char *name )
{
int i;
if( !name || !name[0] )
if( !COM_CheckString( name ))
return 0;
// look through the loaded sprite name list for SpriteName
for( i = 0; i < (MAX_DECALS - 1) && host.draw_decals[i+1][0]; i++ )
for( i = 1; i < MAX_DECALS && host.draw_decals[i][0]; i++ )
{
if( !Q_stricmp( name, host.draw_decals[i+1] ))
return i+1;
if( !Q_stricmp( name, host.draw_decals[i] ))
return i;
}
return 0; // invalid decal
}

View File

@ -86,7 +86,7 @@ void SCR_CheckStartupVids( void )
char *afile, *pfile;
string token;
if( Sys_CheckParm( "-nointro" ) || host.allow_console || cls.demonum != -1 )
if( Sys_CheckParm( "-nointro" ) || host.allow_console || cls.demonum != -1 || GameState->nextstate != STATE_RUNFRAME )
{
// don't run movies where we in developer-mode
cls.movienum = -1;

View File

@ -353,7 +353,7 @@ void V_PostRender( void )
R_AllowFog( false );
R_Set2DMode( true );
if( cls.state == ca_active && cls.scrshot_action != scrshot_mapshot )
if( cls.state == ca_active && cls.signon == SIGNONS && cls.scrshot_action != scrshot_mapshot )
{
SCR_TileClear();
CL_DrawHUD( CL_ACTIVE );

View File

@ -694,7 +694,7 @@ extern convar_t *scr_centertime;
extern convar_t *scr_viewsize;
extern convar_t *scr_download;
extern convar_t *scr_loading;
extern convar_t *scr_dark; // start from dark
extern convar_t *v_dark; // start from dark
extern convar_t *net_graph;
extern convar_t *rate;
@ -837,6 +837,7 @@ _inline cl_entity_t *CL_EDICT_NUM( int n )
void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message );
void CL_ParseTempEntity( sizebuf_t *msg );
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
qboolean CL_RequestMissingResources( void );
//
// cl_scrn.c
@ -911,6 +912,7 @@ qboolean CL_GetEntitySpatialization( struct channel_s *ch );
qboolean CL_GetMovieSpatialization( struct rawchan_s *ch );
void CL_ComputePlayerOrigin( cl_entity_t *clent );
void CL_UpdateEntityFields( cl_entity_t *ent );
void CL_MoveThirdpersonCamera( void );
qboolean CL_IsPlayerIndex( int idx );
void CL_SetIdealPitch( void );
void CL_EmitEntities( void );

View File

@ -1144,7 +1144,8 @@ static qboolean GL_UploadTexture( gltexture_t *tex, rgbdata_t *pic )
normalMap = FBitSet( tex->flags, TF_NORMALMAP ) ? true : false;
numSides = FBitSet( pic->flags, IMAGE_CUBEMAP ) ? 6 : 1;
// uploading texture into video memory
// uploading texture into video memory, change the binding
glState.currentTextures[glState.activeTMU] = tex->texnum;
pglBindTexture( tex->target, tex->texnum );
for( i = 0; i < numSides; i++ )

View File

@ -151,29 +151,10 @@ void R_AddEfrags( cl_entity_t *ent )
lastlink = &ent->efrag;
r_pefragtopnode = NULL;
// NOTE: can't copy these bounds directly into model->mins\model->maxs
// because all other code don't expected this
if( ent->model->type == mod_studio )
for( i = 0; i < 3; i++ )
{
studiohdr_t *phdr = (studiohdr_t *)Mod_StudioExtradata( ent->model );
mstudioseqdesc_t *pseqdesc;
if( !phdr ) return;
pseqdesc = (mstudioseqdesc_t *)((byte *)phdr + phdr->seqindex);
for( i = 0; i < 3; i++ )
{
r_emins[i] = ent->origin[i] + pseqdesc[0].bbmin[i];
r_emaxs[i] = ent->origin[i] + pseqdesc[0].bbmax[i];
}
}
else
{
for( i = 0; i < 3; i++ )
{
r_emins[i] = ent->origin[i] + ent->model->mins[i];
r_emaxs[i] = ent->origin[i] + ent->model->maxs[i];
}
r_emins[i] = ent->origin[i] + ent->model->mins[i];
r_emaxs[i] = ent->origin[i] + ent->model->maxs[i];
}
R_SplitEntityOnNode( cl.worldmodel->nodes );

View File

@ -17,6 +17,7 @@ GNU General Public License for more details.
#include "client.h"
#include "gl_local.h"
#include "mod_local.h"
#include "shake.h"
typedef struct
{
@ -461,6 +462,31 @@ void R_NewMap( void )
R_ParseDetailTextures( filepath );
}
if( v_dark->value )
{
screenfade_t *sf = &clgame.fade;
client_textmessage_t *title;
title = CL_TextMessageGet( "GAMETITLE" );
if( title )
{
// get settings from titles.txt
sf->fadeEnd = title->holdtime + title->fadeout;
sf->fadeReset = title->fadeout;
}
else sf->fadeEnd = sf->fadeReset = 5.0f;
sf->fadeFlags = FFADE_IN;
sf->fader = sf->fadeg = sf->fadeb = 0;
sf->fadealpha = 255;
sf->fadeSpeed = (float)sf->fadealpha / sf->fadeReset;
sf->fadeReset += cl.time;
sf->fadeEnd += sf->fadeReset;
Cvar_SetValue( "v_dark", 0.0f );
}
// clear out efrags in case the level hasn't been reloaded
for( i = 0; i < cl.worldmodel->numleafs; i++ )
cl.worldmodel->leafs[i+1].efrags = NULL;

View File

@ -2130,11 +2130,7 @@ void Con_DrawConsole( void )
case ca_connected:
case ca_validate:
// force to show console always for -dev 3 and higher
if( con.vislines )
{
GL_CleanupAllTextureUnits(); // ugly hack to remove blinking voiceicon.spr during loading
Con_DrawSolidConsole( con.vislines );
}
Con_DrawSolidConsole( con.vislines );
break;
case ca_active:
case ca_cinematic:

View File

@ -912,7 +912,7 @@ int EXPORT Host_Main( const char *progname, int bChangeGame, pfnChangeGame func
Cmd_AddCommand ( "sys_error", Sys_Error_f, "just throw a fatal error to test shutdown procedures");
Cmd_AddCommand ( "host_error", Host_Error_f, "just throw a host error to test shutdown procedures");
Cmd_AddCommand ( "crash", Host_Crash_f, "a way to force a bus error for development reasons");
}
}
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" );

View File

@ -43,6 +43,7 @@ void COM_NewGame( char const *pMapName )
GameState->backgroundMap = false;
GameState->landmarkName[0] = 0;
GameState->loadGame = false;
GameState->newGame = true;
}
@ -56,6 +57,7 @@ void COM_LoadLevel( char const *pMapName, qboolean background )
GameState->backgroundMap = background;
GameState->landmarkName[0] = 0;
GameState->loadGame = false;
GameState->newGame = false;
}

View File

@ -134,6 +134,7 @@ typedef struct
int lightmap_samples; // samples per lightmap (1 or 3)
int version; // model version
qboolean isworld;
qboolean vis_errors; // don't spam about vis
} dbspmodel_t;
typedef struct
@ -447,7 +448,7 @@ void Mod_PrintWorldStats_f( void )
Mod_DecompressVis
===================
*/
static void Mod_DecompressVis( const byte *in, const byte *inend, byte *out, byte *outend )
static void Mod_DecompressVis( dbspmodel_t *bmod, const byte *in, const byte *inend, byte *out, byte *outend )
{
byte *outstart = out;
int c;
@ -456,8 +457,12 @@ static void Mod_DecompressVis( const byte *in, const byte *inend, byte *out, byt
{
if( in == inend )
{
MsgDev( D_WARN, "Mod_DecompressVis: input underrun (decompressed %i of %i output bytes)\n",
(int)(out - outstart), (int)(outend - outstart));
if( !bmod->vis_errors )
{
MsgDev( D_WARN, "Mod_DecompressVis: input underrun (decompressed %i of %i output bytes)\n",
(int)(out - outstart), (int)(outend - outstart));
bmod->vis_errors = true;
}
return;
}
@ -471,8 +476,12 @@ static void Mod_DecompressVis( const byte *in, const byte *inend, byte *out, byt
{
if( in == inend )
{
MsgDev( D_NOTE, "Mod_DecompressVis: input underrun (during zero-run) (decompressed %i of %i output bytes)\n",
(int)(out - outstart), (int)(outend - outstart));
if( !bmod->vis_errors )
{
MsgDev( D_NOTE, "Mod_DecompressVis: input underrun (during zero-run) (decompressed %i of %i output bytes)\n",
(int)(out - outstart), (int)(outend - outstart));
bmod->vis_errors = true;
}
return;
}
@ -480,8 +489,12 @@ static void Mod_DecompressVis( const byte *in, const byte *inend, byte *out, byt
{
if( out == outend )
{
MsgDev( D_NOTE, "Mod_DecompressVis: output overrun (decompressed %i of %i output bytes)\n",
(int)(out - outstart), (int)(outend - outstart));
if( !bmod->vis_errors )
{
MsgDev( D_NOTE, "Mod_DecompressVis: output overrun (decompressed %i of %i output bytes)\n",
(int)(out - outstart), (int)(outend - outstart));
bmod->vis_errors = true;
}
return;
}
*out++ = 0;
@ -2369,7 +2382,7 @@ static void Mod_LoadLeafs( dbspmodel_t *bmod )
byte *outrow = world.visdata + out->cluster * world.visbytes;
byte *outrowend = world.visdata + (out->cluster + 1) * world.visbytes;
Mod_DecompressVis( inrow, inrowend, outrow, outrowend );
Mod_DecompressVis( bmod, inrow, inrowend, outrow, outrowend );
}
else MsgDev( D_WARN, "Mod_LoadLeafs: invalid visofs for leaf #%i\n", i );
}
@ -2621,12 +2634,12 @@ qboolean Mod_LoadBmodelLumps( const byte *mod_base, qboolean isworld )
for( i = 0; i < ARRAYSIZE( extlumps ); i++ )
Mod_LoadLump( mod_base, &extlumps[i], &worldstats[ARRAYSIZE( srclumps ) + i], isworld ? (LUMP_SAVESTATS|LUMP_SILENT) : 0 );
if( loadstat.numerrors )
if( !bmod->isworld && loadstat.numerrors )
{
Con_DPrintf( "Mod_Load%s: %i error(s), %i warning(s)\n", isworld ? "World" : "Brush", loadstat.numerrors, loadstat.numwarnings );
return false; // there were errors, we can't load this map
}
else if( loadstat.numwarnings )
else if( !bmod->isworld && loadstat.numwarnings )
Con_DPrintf( "Mod_Load%s: %i warning(s)\n", isworld ? "World" : "Brush", loadstat.numwarnings );
// load into heap

View File

@ -65,7 +65,6 @@ GNU General Public License for more details.
#define MODEL_WORLD BIT( 29 ) // it's a worldmodel
#define MODEL_CLIENT BIT( 30 ) // client sprite
// goes into world.flags
#define FWORLD_SKYSPHERE BIT( 0 )
#define FWORLD_CUSTOM_SKYBOX BIT( 1 )

View File

@ -23,7 +23,7 @@ GNU General Public License for more details.
#define svc_nop 1 // does nothing
#define svc_disconnect 2 // kick client from server
#define svc_event 3 // playback event queue
#define svc_version 4 // [long] server version
#define svc_changing 4 // changelevel by server request
#define svc_setview 5 // [short] entity number
#define svc_sound 6 // <see code>
#define svc_time 7 // [float] server time

View File

@ -453,11 +453,15 @@ void Mem_PrintList( size_t minallocationsize )
Con_Printf( "memory pool list:\n"" ^3size name\n");
for( pool = poolchain; pool; pool = pool->next )
{
long changed_size = (long)pool->totalsize - (long)pool->lastchecksize;
// poolnames can contain color symbols, make sure what color is reset
if( ((long)pool->totalsize - pool->lastchecksize ) != 0 )
if( changed_size != 0 )
{
Con_Printf( "%10s (%10s actual) %s (^7+%s change)\n", Q_memprint( pool->totalsize ), Q_memprint( pool->realsize ),
pool->name, Q_memprint( pool->totalsize - pool->lastchecksize ));
char sign = (changed_size < 0) ? '-' : '+';
Con_Printf( "%10s (%10s actual) %s (^7%c%s change)\n", Q_memprint( pool->totalsize ), Q_memprint( pool->realsize ),
pool->name, sign, Q_memprint( abs( changed_size )));
}
else
{

View File

@ -432,8 +432,6 @@ extern convar_t sv_skyname;
extern convar_t sv_skyspeed;
extern convar_t sv_skyangle;
extern convar_t sv_consistency;
extern convar_t sv_spawntime;
extern convar_t sv_changetime;
extern convar_t sv_password;
extern convar_t sv_uploadmax;
extern convar_t deathmatch;
@ -473,6 +471,8 @@ void SV_ProcessFile( sv_client_t *cl, char *filename );
void SV_SendResourceList( sv_client_t *cl );
void SV_AddToMaster( netadr_t from, sizebuf_t *msg );
qboolean SV_IsSimulating( void );
qboolean SV_InitGame( void );
void SV_FreeClients( void );
void Master_Add( void );
void Master_Heartbeat( void );
void Master_Packet( void );
@ -564,6 +564,7 @@ int SV_EstimateNeededResources( sv_client_t *cl );
void SV_ClearResourceList( resource_t *pList );
void SV_BatchUploadRequest( sv_client_t *cl );
void SV_SendResources( sv_client_t *cl, sizebuf_t *msg );
void SV_ClearResourceLists( sv_client_t *cl );
int SV_TransferConsistencyInfo( void );
//

View File

@ -204,6 +204,33 @@ int SV_CheckIPRestrictions( netadr_t from )
return 1;
}
/*
================
SV_FindEmptySlot
Get slot # and set client_t pointer for player, if possible
We don't do this search on a "reconnect, we just reuse the slot
================
*/
int SV_FindEmptySlot( netadr_t from, int *pslot, sv_client_t **ppClient )
{
sv_client_t *cl;
int i;
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
{
if( cl->state == cs_free )
{
*ppClient = cl;
*pslot = i;
return 1;
}
}
SV_RejectConnection( from, "server is full\n" );
return 0;
}
/*
==================
SV_ConnectClient
@ -217,6 +244,8 @@ void SV_ConnectClient( netadr_t from )
char physinfo[MAX_PHYSINFO_STRING];
char protinfo[MAX_INFO_STRING];
sv_client_t temp, *cl, *newcl;
qboolean reconnect = false;
int nClientSlot = 0;
int qport, version;
int i, edictnum;
int count = 0;
@ -281,23 +310,6 @@ void SV_ConnectClient( netadr_t from )
Q_strncpy( userinfo, s, sizeof( userinfo ));
// quick reject
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
{
if( cl->state == cs_free || cl->state == cs_zombie )
continue;
if( NET_CompareBaseAdr( from, cl->netchan.remote_address ) && ( cl->netchan.qport == qport || from.port == cl->netchan.remote_address.port ))
{
if( !NET_IsLocalAddress( from ) && ( host.realtime - cl->connection_started ) < sv_reconnect_limit->value )
{
SV_RejectConnection( from, "too soon\n" );
return;
}
break;
}
}
// check connection password (don't verify local client)
if( !NET_IsLocalAddress( from ) && sv_password.string[0] && Q_stricmp( sv_password.string, Info_ValueForKey( userinfo, "password" )))
{
@ -319,39 +331,35 @@ void SV_ConnectClient( netadr_t from )
if( NET_CompareBaseAdr( from, cl->netchan.remote_address ) && ( cl->netchan.qport == qport || from.port == cl->netchan.remote_address.port ))
{
MsgDev( D_INFO, "%s:reconnect\n", NET_AdrToString( from ));
newcl = cl;
goto gotnewcl;
}
}
// find a client slot
newcl = NULL;
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
{
if( cl->state == cs_free )
{
reconnect = true;
newcl = cl;
break;
}
}
if( !newcl )
// A reconnecting client will re-use the slot found above when checking for reconnection.
// the slot will be wiped clean.
if( !reconnect )
{
SV_RejectConnection( from, "server is full\n" );
return;
// cConnect the client if there are empty slots.
if( !SV_FindEmptySlot( from, &nClientSlot, &newcl ))
return;
}
else
{
MsgDev( D_INFO, "%s:reconnect\n", NET_AdrToString( from ));
}
// find a client slot
ASSERT( newcl != NULL );
// build a new connection
// accept the new client
gotnewcl:
// this is the only place a sv_client_t is ever initialized
if( svs.maxclients == 1 ) // save physinfo for singleplayer
Q_strncpy( physinfo, newcl->physinfo, sizeof( physinfo ));
*newcl = temp;
*newcl = temp; // FIXME: don't clearing all the fields
if( svs.maxclients == 1 ) // restore physinfo for singleplayer
Q_strncpy( newcl->physinfo, physinfo, sizeof( physinfo ));
@ -396,6 +404,7 @@ gotnewcl:
// parse some info from the info strings (this can override cl_updaterate)
Q_strncpy( newcl->userinfo, userinfo, sizeof( newcl->userinfo ));
SV_UserinfoChanged( newcl, newcl->userinfo );
SV_ClearResourceLists( newcl );
newcl->next_messagetime = host.realtime + newcl->cl_updaterate;
newcl->next_sendinfotime = 0.0;
@ -1410,7 +1419,6 @@ void SV_SendServerdata( sizebuf_t *msg, sv_client_t *cl )
MSG_WriteString( msg, sv.name );
MSG_WriteString( msg, STRING( svgame.edicts->v.message )); // Map Message
MSG_WriteOneBit( msg, sv.background ); // tell client about background map
MSG_WriteOneBit( msg, svgame.globals->changelevel );
MSG_WriteString( msg, GI->gamefolder );
MSG_WriteLong( msg, host.features );
@ -2489,6 +2497,8 @@ void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
client_frame_t *frame;
char *s;
ASSERT( cl->frames != NULL );
// calc ping time
frame = &cl->frames[cl->netchan.incoming_acknowledged & SV_UPDATE_MASK];

View File

@ -357,6 +357,12 @@ void SV_ClearResourceList( resource_t *pList )
pList->pNext = pList;
}
void SV_ClearResourceLists( sv_client_t *cl )
{
SV_ClearResourceList( &cl->resourcesneeded );
SV_ClearResourceList( &cl->resourcesonhand );
}
int SV_EstimateNeededResources( sv_client_t *cl )
{
int missing = 0;

View File

@ -629,7 +629,7 @@ void SV_WriteEntitiesToClient( sv_client_t *cl, sizebuf_t *msg )
svs.next_client_entities = 0;
// delta is broken for now, cannot keep connected clients
SV_FinalMessage( "Server will restart due delta is outdated", true );
SV_FinalMessage( "Server will restart due delta is outdated\n", true );
}
// copy the entity states out

View File

@ -4948,7 +4948,7 @@ qboolean SV_LoadProgs( const char *name )
svgame.stringspool = Mem_AllocPool( "Server Strings" );
// fire once
MsgDev( D_INFO, "Dll loaded for mod %s\n", svgame.dllFuncs.pfnGetGameDescription( ));
Con_Printf( "Dll loaded for game ^2\"%s\"\n", svgame.dllFuncs.pfnGetGameDescription( ));
// all done, initialize game
svgame.dllFuncs.pfnGameInit();

View File

@ -478,17 +478,15 @@ void SV_ActivateServer( int runPhysics )
// parse user-specified resources
SV_CreateGenericResources();
sv.state = ss_active;
if( runPhysics )
{
sv.frametime = bound( 0.1, sv_spawntime.value, 0.8 );
numFrames = (svs.maxclients <= 1) ? 2 : 8;
sv.frametime = 0.1;
}
else
{
sv.frametime = bound( 0.001, sv_changetime.value, 0.1 );
numFrames = 0;
sv.frametime = (svgame.globals->changelevel) ? 0.1 : 0.001;
numFrames = 1;
}
// run some frames to allow everything to settle
@ -512,14 +510,6 @@ void SV_ActivateServer( int runPhysics )
Netchan_Clear( &cl->netchan );
cl->delta_sequence = -1;
if( svs.maxclients <= 1 )
SV_SendServerdata( &msg, cl );
else SV_BuildReconnect( &cl->netchan.message );
Netchan_CreateFragments( &cl->netchan, &msg );
Netchan_FragSend( &cl->netchan );
MSG_Clear( &msg );
}
// invoke to refresh all movevars
@ -543,6 +533,7 @@ void SV_ActivateServer( int runPhysics )
Mod_FreeUnused ();
host.movevars_changed = true;
sv.state = ss_active;
Con_DPrintf( "level loaded at %.2f sec\n", Sys_DoubleTime() - svs.timestart );
@ -574,6 +565,7 @@ void SV_DeactivateServer( void )
svgame.globals->time = sv.time;
svgame.dllFuncs.pfnServerDeactivate();
sv.state = ss_dead;
SV_FreeEdicts ();
@ -594,7 +586,6 @@ void SV_DeactivateServer( void )
svgame.numEntities = svs.maxclients + 1; // clients + world
svgame.globals->startspot = 0;
svgame.globals->mapname = 0;
sv.state = ss_dead;
}
/*
@ -634,6 +625,7 @@ void SV_ShutdownGame( void )
if( !GameState->loadGame )
SV_ClearGameState();
SV_FinalMessage( "", true );
S_StopBackgroundTrack();
if( GameState->newGame )
@ -647,24 +639,6 @@ void SV_ShutdownGame( void )
}
}
/*
================
SV_AllocClientFrames
allocate delta-compression frames for each client
================
*/
void SV_AllocClientFrames( void )
{
sv_client_t *cl;
int i;
for( i = 0, cl = svs.clients; i < svs.maxclients; i++, cl++ )
{
cl->frames = Z_Realloc( cl->frames, SV_UPDATE_BACKUP * sizeof( client_frame_t ));
}
}
/*
================
SV_SetupClients
@ -680,11 +654,13 @@ void SV_SetupClients( void )
if( svs.maxclients != (int)sv_maxclients->value )
changed_maxclients = true;
svs.maxclients = sv_maxclients->value; // copy the actual value from cvar
if( !changed_maxclients ) return; // nothing to change
// if clients count was changed we need to run full shutdown procedure
// Host_ShutdownServer();
if( svs.maxclients ) Host_ShutdownServer();
// copy the actual value from cvar
svs.maxclients = (int)sv_maxclients->value;
// dedicated servers are can't be single player and are usually DM
if( host.type == HOST_DEDICATED )
@ -727,7 +703,6 @@ qboolean SV_SpawnServer( const char *mapname, const char *startspot, qboolean ba
edict_t *ent;
SV_SetupClients();
SV_AllocClientFrames();
if( !SV_InitGame( ))
return false;

View File

@ -98,9 +98,6 @@ CVAR_DEFINE_AUTO( sv_skydir_z, "1", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "sky rotation
CVAR_DEFINE_AUTO( sv_skyangle, "0", FCVAR_MOVEVARS|FCVAR_UNLOGGED, "skybox rotational angle (in degrees)" );
CVAR_DEFINE_AUTO( sv_skyspeed, "0", 0, "skybox rotational speed" );
CVAR_DEFINE( sv_spawntime, "host_spawntime", "0.1", FCVAR_ARCHIVE, "host.frametime on spawn new map (force to 0.8 if have problems)" );
CVAR_DEFINE( sv_changetime, "host_changetime", "0.001", FCVAR_ARCHIVE, "host.frametime on changelevel (force to 0.1 if have player stucks)" );
// obsolete cvars which we should keep because game DLL's will be relies on it
CVAR_DEFINE_AUTO( showtriggers, "0", FCVAR_LATCH, "debug cvar shows triggers" );
CVAR_DEFINE_AUTO( sv_airmove, "1", FCVAR_SERVER, "obsolete, compatibility issues" );
@ -320,10 +317,7 @@ void SV_ReadPackets( void )
continue;
if( cl->netchan.remote_address.port != net_from.port )
{
MsgDev( D_NOTE, "SV_ReadPackets: fixing up a translated port\n");
cl->netchan.remote_address.port = net_from.port;
}
if( Netchan_Process( &cl->netchan, &net_message ))
{
@ -331,7 +325,7 @@ void SV_ReadPackets( void )
SetBits( cl->flags, FCL_SEND_NET_MESSAGE ); // reply at end of frame
// this is a valid, sequenced packet, so process it
if( cl->state != cs_zombie )
if( cl->frames != NULL && cl->state != cs_zombie )
{
SV_ExecuteClientMessage( cl, &net_message );
svgame.globals->frametime = sv.frametime;
@ -350,7 +344,7 @@ void SV_ReadPackets( void )
SetBits( cl->flags, FCL_SEND_NET_MESSAGE ); // reply at end of frame
// this is a valid, sequenced packet, so process it
if( cl->state != cs_zombie )
if( cl->frames != NULL && cl->state != cs_zombie )
{
SV_ExecuteClientMessage( cl, &net_message );
svgame.globals->frametime = sv.frametime;
@ -785,10 +779,6 @@ void SV_Init( void )
sv_hostmap = Cvar_Get( "hostmap", GI->startmap, 0, "keep name of last entered map" );
Cvar_RegisterVariable (&sv_password);
Cvar_RegisterVariable (&sv_lan);
Cvar_RegisterVariable (&sv_spawntime);
Cvar_RegisterVariable (&sv_changetime);
Cvar_RegisterVariable (&violence_ablood);
Cvar_RegisterVariable (&violence_hblood);
Cvar_RegisterVariable (&violence_agibs);
@ -824,11 +814,25 @@ void SV_FinalMessage( const char *message, qboolean reconnect )
int i;
MSG_Init( &msg, "FinalMessage", msg_buf, sizeof( msg_buf ));
MSG_BeginServerCmd( &msg, svc_print );
MSG_WriteString( &msg, va( "%s\n", message ));
if( reconnect ) SV_BuildReconnect( &msg );
else MSG_BeginServerCmd( &msg, svc_disconnect );
if( COM_CheckString( message ))
{
MSG_BeginServerCmd( &msg, svc_print );
MSG_WriteString( &msg, message );
}
if( reconnect )
{
MSG_BeginServerCmd( &msg, svc_changing );
if( GameState->loadGame || svs.maxclients > 1 )
MSG_WriteOneBit( &msg, 1 ); // changelevel
else MSG_WriteOneBit( &msg, 0 );
}
else
{
MSG_BeginServerCmd( &msg, svc_disconnect );
}
// send it twice
// stagger the packets to crutch operating system limited buffers
@ -841,6 +845,13 @@ void SV_FinalMessage( const char *message, qboolean reconnect )
Netchan_Transmit( &cl->netchan, MSG_GetNumBytesWritten( &msg ), MSG_GetData( &msg ));
}
/*
================
SV_FreeClients
release server clients
================
*/
void SV_FreeClients( void )
{
if( svs.maxclients != 0 )
@ -859,8 +870,6 @@ void SV_FreeClients( void )
svs.num_client_entities = 0;
svs.next_client_entities = 0;
}
svs.maxclients = 0;
}
}
@ -888,11 +897,13 @@ void SV_Shutdown( const char *finalmsg )
NET_Config( false );
SV_UnloadProgs ();
CL_Drop();
// free current level
memset( &sv, 0, sizeof( sv ));
SV_FreeClients();
svs.maxclients = 0;
Log_Printf( "Server shutdown\n" );
Log_Close();

View File

@ -886,7 +886,7 @@ static edict_t *SV_PushMove( edict_t *pusher, float movetime )
sv_pushed_t *p, *pushed_p;
edict_t *check;
if( VectorIsNull( pusher->v.velocity ))
if( svgame.globals->changelevel || VectorIsNull( pusher->v.velocity ))
{
pusher->v.ltime += movetime;
return NULL;
@ -1004,7 +1004,7 @@ static edict_t *SV_PushRotate( edict_t *pusher, float movetime )
vec3_t org, org2, temp;
edict_t *check;
if( VectorIsNull( pusher->v.avelocity ))
if( svgame.globals->changelevel || VectorIsNull( pusher->v.avelocity ))
{
pusher->v.ltime += movetime;
return NULL;

View File

@ -871,7 +871,7 @@ SAVERESTOREDATA *SV_LoadSaveData( const char *level )
int i, id, size, version;
Q_snprintf( name, sizeof( name ), "save/%s.HL1", level );
Con_Printf( "Loading game from %s...\n", name );
Con_DPrintf( "Loading game from %s...\n", name );
pFile = FS_Open( name, "rb", true );
if( !pFile )
@ -1957,6 +1957,7 @@ void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char
}
SV_InactivateClients ();
SV_FinalMessage( "", true );
SV_DeactivateServer ();
if( !SV_SpawnServer( level, startspot, false ))
@ -2142,8 +2143,8 @@ qboolean SV_LoadGame( const char *pPath )
if( !FS_FileExists( pPath, true ))
return false;
SV_InitGameProgs();
if( !svgame.hInstance )
// initialize game if needs
if( !SV_InitGame( ))
return false;
pFile = FS_Open( pPath, "rb", true );

View File

@ -33,6 +33,9 @@ GNU General Public License for more details.
#include <math.h>
#define bound( min, num, max ) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min))
#define SetBits( iBitVector, bits ) ((iBitVector) = (iBitVector) | (bits))
#define ClearBits( iBitVector, bits ) ((iBitVector) = (iBitVector) & ~(bits))
#define FBitSet( iBitVector, bit ) ((iBitVector) & (bit))
typedef int (*cmpfunc)( const void *a, const void *b );

View File

@ -336,15 +336,10 @@ UI_PlayerSetup_Init
*/
static void UI_PlayerSetup_Init( void )
{
bool game_hlRally = FALSE;
int addFlags = 0;
memset( &uiPlayerSetup, 0, sizeof( uiPlayerSetup_t ));
// disable playermodel preview for HLRally to prevent crash
if( !stricmp( gMenu.m_gameinfo.gamefolder, "hlrally" ))
game_hlRally = TRUE;
if( gMenu.m_gameinfo.flags & GFL_NOMODELS )
addFlags |= QMF_INACTIVE;
@ -413,10 +408,10 @@ static void UI_PlayerSetup_Init( void )
uiPlayerSetup.model.generic.id = ID_MODEL;
uiPlayerSetup.model.generic.type = QMTYPE_SPINCONTROL;
uiPlayerSetup.model.generic.flags = QMF_CENTER_JUSTIFY|QMF_HIGHLIGHTIFFOCUS|QMF_DROPSHADOW|addFlags;
uiPlayerSetup.model.generic.x = game_hlRally ? 320 : 702;
uiPlayerSetup.model.generic.y = game_hlRally ? 320 : 590;
uiPlayerSetup.model.generic.width = game_hlRally ? 256 : 176;
uiPlayerSetup.model.generic.height = game_hlRally ? 36 : 32;
uiPlayerSetup.model.generic.x = FBitSet( gMenu.m_gameinfo.flags, GFL_NOMODELS ) ? 320 : 702;
uiPlayerSetup.model.generic.y = FBitSet( gMenu.m_gameinfo.flags, GFL_NOMODELS ) ? 320 : 590;
uiPlayerSetup.model.generic.width = FBitSet( gMenu.m_gameinfo.flags, GFL_NOMODELS ) ? 256 : 176;
uiPlayerSetup.model.generic.height = FBitSet( gMenu.m_gameinfo.flags, GFL_NOMODELS ) ? 36 : 32;
uiPlayerSetup.model.generic.callback = UI_PlayerSetup_Callback;
uiPlayerSetup.model.generic.statusText = "Select a model for representation in multiplayer";
uiPlayerSetup.model.minValue = 0;
@ -474,11 +469,11 @@ static void UI_PlayerSetup_Init( void )
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.done );
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.AdvOptions );
// disable playermodel preview for HLRally to prevent crash
if( game_hlRally == FALSE )
if( !FBitSet( gMenu.m_gameinfo.flags, GFL_NOMODELS ))
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.view );
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.name );
if( !( gMenu.m_gameinfo.flags & GFL_NOMODELS ))
if( !FBitSet( gMenu.m_gameinfo.flags, GFL_NOMODELS ))
{
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.model );
UI_AddItem( &uiPlayerSetup.menu, (void *)&uiPlayerSetup.topColor );

View File

@ -51,18 +51,6 @@ Package=<4>
###############################################################################
Project: "mainui2"=.\mainui2\mainui2.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Project: "vgui"=.\utils\vgui\lib\vgui.dsp - Package Owner=<4>
Package=<5>