09 Mar 2018
This commit is contained in:
parent
dadc30ca94
commit
49c19a90ab
|
@ -32,11 +32,14 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
|
|||
}
|
||||
|
||||
// resource was missed on server
|
||||
// if( pResource->nDownloadSize <= 0 )
|
||||
// return true;
|
||||
if( pResource->nDownloadSize == -1 )
|
||||
{
|
||||
ClearBits( pResource->ucFlags, RES_FATALIFMISSING );
|
||||
return true;
|
||||
}
|
||||
|
||||
if( pResource->type == t_sound )
|
||||
Q_strncpy( filepath, va( "sound/%s", pResource->szFileName ), sizeof( filepath ));
|
||||
Q_strncpy( filepath, va( "%s%s", DEFAULT_SOUNDPATH, pResource->szFileName ), sizeof( filepath ));
|
||||
else Q_strncpy( filepath, pResource->szFileName, sizeof( filepath ));
|
||||
|
||||
if( !COM_IsSafeFileToDownload( filepath ))
|
||||
|
@ -67,7 +70,8 @@ qboolean CL_CheckFile( sizebuf_t *msg, resource_t *pResource )
|
|||
}
|
||||
|
||||
MSG_BeginClientCmd( msg, clc_stringcmd );
|
||||
MSG_WriteString( msg, va( "dlfile %s", pResource->szFileName ));
|
||||
MSG_WriteString( msg, va( "dlfile %s", filepath ));
|
||||
host.downloadcount++;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2246,25 +2246,29 @@ CL_FindModelIndex
|
|||
*/
|
||||
int CL_FindModelIndex( const char *m )
|
||||
{
|
||||
char filepath[MAX_QPATH];
|
||||
static float lasttimewarn;
|
||||
int i;
|
||||
|
||||
if( !COM_CheckString( m ))
|
||||
return 0;
|
||||
|
||||
Q_strncpy( filepath, m, sizeof( filepath ));
|
||||
COM_FixSlashes( filepath );
|
||||
|
||||
for( i = 0; i < cl.nummodels; i++ )
|
||||
{
|
||||
if( !cl.models[i+1] )
|
||||
continue;
|
||||
|
||||
if( !Q_stricmp( cl.models[i+1]->name, m ))
|
||||
return i;
|
||||
if( !Q_stricmp( cl.models[i+1]->name, filepath ))
|
||||
return i+1;
|
||||
}
|
||||
|
||||
if( lasttimewarn < host.realtime )
|
||||
{
|
||||
// tell user about problem (but don't spam console)
|
||||
Con_Printf( S_ERROR "%s not precached\n", m );
|
||||
Con_Printf( S_ERROR "%s not precached\n", filepath );
|
||||
lasttimewarn = host.realtime + 1.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,9 +88,13 @@ qboolean CL_Initialized( void )
|
|||
//======================================================================
|
||||
qboolean CL_IsInGame( void )
|
||||
{
|
||||
if( host.type == HOST_DEDICATED ) return true; // always active for dedicated servers
|
||||
if( CL_GetMaxClients() > 1 ) return true; // always active for multiplayer
|
||||
return ( cls.key_dest == key_game ); // active if not menu or console
|
||||
if( host.type == HOST_DEDICATED )
|
||||
return true; // always active for dedicated servers
|
||||
|
||||
if( cl.background || CL_GetMaxClients() > 1 )
|
||||
return true; // always active for multiplayer or background map
|
||||
|
||||
return ( cls.key_dest == key_game ); // active if not menu or console
|
||||
}
|
||||
|
||||
qboolean CL_IsInMenu( void )
|
||||
|
@ -623,7 +627,7 @@ void CL_CreateCmd( void )
|
|||
{
|
||||
VectorCopy( angles, pcmd->cmd.viewangles );
|
||||
VectorCopy( angles, cl.viewangles );
|
||||
pcmd->cmd.msec = 0;
|
||||
if( !cl.background ) pcmd->cmd.msec = 0;
|
||||
}
|
||||
|
||||
// demo always have commands so don't overwrite them
|
||||
|
@ -1671,103 +1675,6 @@ void CL_SetupOverviewParams( void )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
======================
|
||||
CL_PrepSound
|
||||
|
||||
Call before entering a new level, or after changing dlls
|
||||
======================
|
||||
*/
|
||||
void CL_PrepSound( void )
|
||||
{
|
||||
int i, sndcount;
|
||||
|
||||
MsgDev( D_NOTE, "CL_PrepSound: %s\n", clgame.mapname );
|
||||
for( i = 0, sndcount = 0; i < MAX_SOUNDS && cl.sound_precache[i+1][0]; i++ )
|
||||
sndcount++; // total num sounds
|
||||
|
||||
S_BeginRegistration();
|
||||
|
||||
for( i = 0; i < MAX_SOUNDS && cl.sound_precache[i+1][0]; i++ )
|
||||
{
|
||||
cl.sound_index[i+1] = S_RegisterSound( cl.sound_precache[i+1] );
|
||||
Cvar_SetValue( "scr_loading", scr_loading->value + 5.0f / sndcount );
|
||||
if( cl_allow_levelshots->value || host_developer.value || cl.background )
|
||||
SCR_UpdateScreen();
|
||||
}
|
||||
|
||||
S_EndRegistration();
|
||||
cl.audio_prepped = true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_PrepVideo
|
||||
|
||||
Call before entering a new level, or after changing dlls
|
||||
=================
|
||||
*/
|
||||
void CL_PrepVideo( void )
|
||||
{
|
||||
model_t *mod;
|
||||
int i;
|
||||
|
||||
if( !cl.models[WORLD_INDEX] )
|
||||
return; // no map loaded
|
||||
|
||||
Cvar_SetValue( "scr_loading", 0.0f ); // reset progress bar
|
||||
MsgDev( D_NOTE, "CL_PrepVideo: %s\n", clgame.mapname );
|
||||
|
||||
// let the render dll load the map
|
||||
world.loading = true;
|
||||
cl.worldmodel = Mod_LoadModel( cl.models[WORLD_INDEX], true );
|
||||
world.loading = false;
|
||||
Cvar_SetValue( "scr_loading", 25.0f );
|
||||
|
||||
SCR_UpdateScreen();
|
||||
|
||||
for( i = WORLD_INDEX; i < cl.nummodels - 1; i++ )
|
||||
{
|
||||
Mod_LoadModel( cl.models[i+1], false );
|
||||
Cvar_SetValue( "scr_loading", scr_loading->value + 75.0f / cl.nummodels );
|
||||
if( cl_allow_levelshots->value || host_developer.value || cl.background )
|
||||
SCR_UpdateScreen();
|
||||
}
|
||||
|
||||
// load tempent sprites (glowshell, muzzleflashes etc)
|
||||
CL_LoadClientSprites ();
|
||||
|
||||
// invalidate all decal indexes
|
||||
memset( cl.decal_index, 0, sizeof( cl.decal_index ));
|
||||
|
||||
CL_ClearWorld ();
|
||||
|
||||
R_NewMap(); // tell the render about new map
|
||||
|
||||
CL_SetupOverviewParams(); // set overview bounds
|
||||
|
||||
if( clgame.drawFuncs.R_NewMap != NULL )
|
||||
clgame.drawFuncs.R_NewMap();
|
||||
|
||||
// release unused SpriteTextures
|
||||
for( i = 1, mod = clgame.sprites; i < MAX_CLIENT_SPRITES; i++, mod++ )
|
||||
{
|
||||
if( mod->needload == NL_UNREFERENCED && COM_CheckString( mod->name ))
|
||||
Mod_UnloadSpriteModel( mod );
|
||||
}
|
||||
|
||||
Mod_FreeUnused ();
|
||||
|
||||
Cvar_SetValue( "scr_loading", 100.0f ); // all done
|
||||
|
||||
if( !host_developer.value )
|
||||
Con_ClearNotify(); // clear any lines of console text
|
||||
|
||||
cl.video_prepped = true;
|
||||
|
||||
SCR_UpdateScreen ();
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_ConnectionlessPacket
|
||||
|
@ -1803,7 +1710,7 @@ void CL_ConnectionlessPacket( netadr_t from, sizebuf_t *msg )
|
|||
}
|
||||
|
||||
CL_Reconnect( true );
|
||||
UI_SetActiveMenu( false );
|
||||
UI_SetActiveMenu( cl.background );
|
||||
}
|
||||
else if( !Q_strcmp( c, "info" ))
|
||||
{
|
||||
|
@ -2136,7 +2043,7 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
|||
if( COM_CheckString( filename ) && successfully_received )
|
||||
{
|
||||
if( filename[0] != '!' )
|
||||
Con_Printf( "Processing %s\n", filename );
|
||||
Con_Printf( "processing %s\n", filename );
|
||||
}
|
||||
else if( !successfully_received )
|
||||
{
|
||||
|
@ -2152,15 +2059,23 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
|||
{
|
||||
if( !Q_strnicmp( filename, "!MD5", 4 ))
|
||||
{
|
||||
COM_HexConvert( pfilename + 4, 32, rgucMD5_hash );
|
||||
COM_HexConvert( filename + 4, 32, rgucMD5_hash );
|
||||
|
||||
if( !memcmp( p->rgucMD5_hash, rgucMD5_hash, 16 ))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !Q_stricmp( p->szFileName, filename ))
|
||||
break;
|
||||
if( p->type == t_generic )
|
||||
{
|
||||
if( !Q_stricmp( p->szFileName, filename ))
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !Q_stricmp( p->szFileName, pfilename ))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2200,6 +2115,11 @@ void CL_ProcessFile( qboolean successfully_received, const char *filename )
|
|||
|
||||
if( cls.state != ca_disconnected )
|
||||
{
|
||||
host.downloadcount = 0;
|
||||
|
||||
for( p = cl.resourcesneeded.pNext; p != &cl.resourcesneeded; p = p->pNext )
|
||||
host.downloadcount++;
|
||||
|
||||
if( cl.resourcesneeded.pNext == &cl.resourcesneeded )
|
||||
{
|
||||
byte msg_buf[MAX_INIT_MSG];
|
||||
|
@ -2312,33 +2232,10 @@ void CL_Physinfo_f( void )
|
|||
Con_Printf( "Total %i symbols\n", Q_strlen( cls.physinfo ));
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_Precache_f
|
||||
|
||||
The server will send this command right
|
||||
before allowing the client into the server
|
||||
=================
|
||||
*/
|
||||
void CL_Precache_f( void )
|
||||
{
|
||||
int spawncount;
|
||||
|
||||
spawncount = Q_atoi( Cmd_Argv( 1 ));
|
||||
|
||||
CL_PrepSound();
|
||||
CL_PrepVideo();
|
||||
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_stringcmd );
|
||||
MSG_WriteString( &cls.netchan.message, va( "spawn %i\n", spawncount ));
|
||||
}
|
||||
|
||||
qboolean CL_PrecacheResources( void )
|
||||
{
|
||||
resource_t *pRes;
|
||||
|
||||
S_BeginRegistration();
|
||||
|
||||
// NOTE: world need to be loaded as first model
|
||||
for( pRes = cl.resourcesonhand.pNext; pRes && pRes != &cl.resourcesonhand; pRes = pRes->pNext )
|
||||
{
|
||||
|
@ -2366,7 +2263,6 @@ qboolean CL_PrecacheResources( void )
|
|||
|
||||
if( FBitSet( pRes->ucFlags, RES_FATALIFMISSING ))
|
||||
{
|
||||
S_EndRegistration();
|
||||
CL_Disconnect_f();
|
||||
return false;
|
||||
}
|
||||
|
@ -2374,6 +2270,8 @@ qboolean CL_PrecacheResources( void )
|
|||
}
|
||||
}
|
||||
|
||||
S_BeginRegistration();
|
||||
|
||||
// precache all the remaining resources where order is doesn't matter
|
||||
for( pRes = cl.resourcesonhand.pNext; pRes && pRes != &cl.resourcesonhand; pRes = pRes->pNext )
|
||||
{
|
||||
|
@ -2383,25 +2281,33 @@ qboolean CL_PrecacheResources( void )
|
|||
switch( pRes->type )
|
||||
{
|
||||
case t_sound:
|
||||
if( FBitSet( pRes->ucFlags, RES_WASMISSING ))
|
||||
if( pRes->nIndex != -1 )
|
||||
{
|
||||
cl.sound_precache[pRes->nIndex][0] = 0;
|
||||
cl.sound_index[pRes->nIndex] = 0;
|
||||
if( FBitSet( pRes->ucFlags, RES_WASMISSING ))
|
||||
{
|
||||
cl.sound_precache[pRes->nIndex][0] = 0;
|
||||
cl.sound_index[pRes->nIndex] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( cl.sound_precache[pRes->nIndex], pRes->szFileName, sizeof( cl.sound_precache[0] ));
|
||||
cl.sound_index[pRes->nIndex] = S_RegisterSound( pRes->szFileName );
|
||||
|
||||
if( !cl.sound_index[pRes->nIndex] )
|
||||
{
|
||||
if( FBitSet( pRes->ucFlags, RES_FATALIFMISSING ))
|
||||
{
|
||||
S_EndRegistration();
|
||||
CL_Disconnect_f();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Q_strncpy( cl.sound_precache[pRes->nIndex], pRes->szFileName, sizeof( cl.sound_precache[0] ));
|
||||
cl.sound_index[pRes->nIndex] = S_RegisterSound( pRes->szFileName );
|
||||
|
||||
if( !cl.sound_index[pRes->nIndex] )
|
||||
{
|
||||
if( FBitSet( pRes->ucFlags, RES_FATALIFMISSING ))
|
||||
{
|
||||
S_EndRegistration();
|
||||
CL_Disconnect_f();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// client sounds
|
||||
S_RegisterSound( pRes->szFileName );
|
||||
}
|
||||
break;
|
||||
case t_skin:
|
||||
|
@ -2410,20 +2316,27 @@ qboolean CL_PrecacheResources( void )
|
|||
cl.nummodels = Q_max( cl.nummodels, pRes->nIndex + 1 );
|
||||
if( pRes->szFileName[0] != '*' )
|
||||
{
|
||||
cl.models[pRes->nIndex] = Mod_ForName( pRes->szFileName, false, true );
|
||||
|
||||
if( cl.models[pRes->nIndex] == NULL )
|
||||
if( pRes->nIndex != -1 )
|
||||
{
|
||||
if( pRes->ucFlags != 0 )
|
||||
MsgDev( D_WARN, "model %s not found and not available\n", pRes->szFileName );
|
||||
cl.models[pRes->nIndex] = Mod_ForName( pRes->szFileName, false, true );
|
||||
|
||||
if( FBitSet( pRes->ucFlags, RES_FATALIFMISSING ))
|
||||
if( cl.models[pRes->nIndex] == NULL )
|
||||
{
|
||||
S_EndRegistration();
|
||||
CL_Disconnect_f();
|
||||
return false;
|
||||
if( pRes->ucFlags != 0 )
|
||||
MsgDev( D_WARN, "model %s not found and not available\n", pRes->szFileName );
|
||||
|
||||
if( FBitSet( pRes->ucFlags, RES_FATALIFMISSING ))
|
||||
{
|
||||
S_EndRegistration();
|
||||
CL_Disconnect_f();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CL_LoadClientSprite( pRes->szFileName );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case t_decal:
|
||||
|
@ -2611,7 +2524,6 @@ void CL_InitLocal( void )
|
|||
Cmd_AddCommand ("reconnect", CL_Reconnect_f, "reconnect to current level" );
|
||||
|
||||
Cmd_AddCommand ("rcon", CL_Rcon_f, "sends a command to the server console (rcon_password and rcon_address required)" );
|
||||
Cmd_AddCommand ("precache", CL_Precache_f, "precache specified resource (by index)" );
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
@ -2662,9 +2574,6 @@ void Host_ClientBegin( void )
|
|||
// if client is not active, do nothing
|
||||
if( !cls.initialized ) return;
|
||||
|
||||
// evaluate console animation
|
||||
Con_RunConsole ();
|
||||
|
||||
// exec console commands
|
||||
Cbuf_Execute ();
|
||||
|
||||
|
|
|
@ -654,6 +654,7 @@ qboolean CL_RequestMissingResources( void )
|
|||
if( p == &cl.resourcesneeded )
|
||||
{
|
||||
cls.dl.doneregistering = true;
|
||||
host.downloadcount = 0;
|
||||
cls.dl.custom = false;
|
||||
}
|
||||
else if( !FBitSet( p->ucFlags, RES_WASMISSING ))
|
||||
|
@ -673,6 +674,9 @@ void CL_BatchResourceRequest( void )
|
|||
|
||||
MSG_Init( &msg, "Resource Batch", data, sizeof( data ));
|
||||
|
||||
// client resources is not precached by server
|
||||
CL_AddClientResources();
|
||||
|
||||
for( p = cl.resourcesneeded.pNext; p && p != &cl.resourcesneeded; p = n )
|
||||
{
|
||||
n = p->pNext;
|
||||
|
@ -748,6 +752,7 @@ void CL_BatchResourceRequest( void )
|
|||
CL_RegisterResources( &msg );
|
||||
}
|
||||
|
||||
Msg( "download request %d bytes\n", MSG_GetNumBytesWritten( &msg ));
|
||||
Netchan_CreateFragments( &cls.netchan, &msg );
|
||||
Netchan_FragSend( &cls.netchan );
|
||||
}
|
||||
|
@ -765,7 +770,7 @@ int CL_EstimateNeededResources( void )
|
|||
{
|
||||
case t_sound:
|
||||
nSize = FS_FileSize( va( "sound/%s", p->szFileName ), false );
|
||||
if( p->szFileName[0] != '*' && ( nSize == 0 || nSize == -1 ))
|
||||
if( p->szFileName[0] != '*' && nSize == -1 )
|
||||
{
|
||||
SetBits( p->ucFlags, RES_WASMISSING );
|
||||
nTotalSize += p->nDownloadSize;
|
||||
|
@ -773,7 +778,7 @@ int CL_EstimateNeededResources( void )
|
|||
break;
|
||||
case t_model:
|
||||
nSize = FS_FileSize( p->szFileName, false );
|
||||
if( p->szFileName[0] != '*' && p->ucFlags != 0 && ( nSize == 0 || nSize == -1 ))
|
||||
if( p->szFileName[0] != '*' && p->ucFlags && nSize == -1 )
|
||||
{
|
||||
SetBits( p->ucFlags, RES_WASMISSING );
|
||||
nTotalSize += p->nDownloadSize;
|
||||
|
@ -783,7 +788,7 @@ int CL_EstimateNeededResources( void )
|
|||
case t_generic:
|
||||
case t_eventscript:
|
||||
nSize = FS_FileSize( p->szFileName, false );
|
||||
if( nSize == 0 || nSize == -1 )
|
||||
if( nSize == -1 )
|
||||
{
|
||||
SetBits( p->ucFlags, RES_WASMISSING );
|
||||
nTotalSize += p->nDownloadSize;
|
||||
|
@ -1152,20 +1157,14 @@ void CL_ParseServerData( sizebuf_t *msg )
|
|||
cls.scrshot_request = scrshot_plaque; // request levelshot even if exist (check filetime)
|
||||
}
|
||||
|
||||
// begin fetching modellist
|
||||
MSG_BeginClientCmd( &cls.netchan.message, clc_stringcmd );
|
||||
#if 0
|
||||
MSG_WriteString( &cls.netchan.message, va( "modellist %i\n", cl.servercount ));
|
||||
#else
|
||||
MSG_WriteString( &cls.netchan.message, va( "sendres %i\n", cl.servercount ));
|
||||
#endif
|
||||
// need to prep refresh at next oportunity
|
||||
cl.video_prepped = false;
|
||||
cl.audio_prepped = false;
|
||||
// request resources from server
|
||||
CL_ServerCommand( true, "sendres %i\n", cl.servercount );
|
||||
|
||||
memset( &clgame.movevars, 0, sizeof( clgame.movevars ));
|
||||
memset( &clgame.oldmovevars, 0, sizeof( clgame.oldmovevars ));
|
||||
memset( &clgame.centerPrint, 0, sizeof( clgame.centerPrint ));
|
||||
cl.video_prepped = false;
|
||||
cl.audio_prepped = false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2277,6 +2276,7 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
{
|
||||
size_t bufStart, playerbytes;
|
||||
int cmd, param1, param2;
|
||||
int old_background;
|
||||
|
||||
cls_message_debug.parsing = true; // begin parsing
|
||||
starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
|
||||
|
@ -2334,6 +2334,7 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
cl.frames[cl.parsecountmod].graphdata.event += MSG_GetNumBytesRead( msg ) - bufStart;
|
||||
break;
|
||||
case svc_changing:
|
||||
old_background = cl.background;
|
||||
if( MSG_ReadOneBit( msg ))
|
||||
{
|
||||
cls.changelevel = true;
|
||||
|
@ -2362,6 +2363,7 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
// g-cont. local client skip the challenge
|
||||
if( SV_Active()) cls.state = ca_disconnected;
|
||||
else cls.state = ca_connecting;
|
||||
cl.background = old_background;
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -319,7 +319,7 @@ void SCR_BeginLoadingPlaque( qboolean is_background )
|
|||
if( cls.state == ca_disconnected || cls.disable_screen )
|
||||
return; // already set
|
||||
|
||||
cls.draw_changelevel = is_background ? false : true;
|
||||
cls.draw_changelevel = !is_background;
|
||||
SCR_UpdateScreen();
|
||||
cls.disable_screen = host.realtime;
|
||||
cls.disable_servercount = cl.servercount;
|
||||
|
@ -454,6 +454,7 @@ void SCR_UpdateScreen( void )
|
|||
switch( cls.state )
|
||||
{
|
||||
case ca_disconnected:
|
||||
Con_RunConsole ();
|
||||
break;
|
||||
case ca_connecting:
|
||||
case ca_connected:
|
||||
|
@ -461,6 +462,7 @@ void SCR_UpdateScreen( void )
|
|||
SCR_DrawPlaque();
|
||||
break;
|
||||
case ca_active:
|
||||
Con_RunConsole ();
|
||||
V_RenderView();
|
||||
break;
|
||||
case ca_cinematic:
|
||||
|
|
|
@ -46,6 +46,48 @@ model_t *cl_sprite_ricochet = NULL;
|
|||
model_t *cl_sprite_shell = NULL;
|
||||
model_t *cl_sprite_glow = NULL;
|
||||
|
||||
const char *cl_default_sprites[] =
|
||||
{
|
||||
// built-in sprites
|
||||
"sprites/muzzleflash1.spr",
|
||||
"sprites/muzzleflash2.spr",
|
||||
"sprites/muzzleflash3.spr",
|
||||
"sprites/dot.spr",
|
||||
"sprites/animglow01.spr",
|
||||
"sprites/richo1.spr",
|
||||
"sprites/shellchrome.spr",
|
||||
};
|
||||
|
||||
const char *cl_player_shell_sounds[] =
|
||||
{
|
||||
"player/pl_shell1.wav",
|
||||
"player/pl_shell2.wav",
|
||||
"player/pl_shell3.wav",
|
||||
};
|
||||
|
||||
const char *cl_weapon_shell_sounds[] =
|
||||
{
|
||||
"weapons/sshell1.wav",
|
||||
"weapons/sshell2.wav",
|
||||
"weapons/sshell3.wav",
|
||||
};
|
||||
|
||||
const char *cl_ricochet_sounds[] =
|
||||
{
|
||||
"weapons/ric1.wav",
|
||||
"weapons/ric2.wav",
|
||||
"weapons/ric3.wav",
|
||||
"weapons/ric4.wav",
|
||||
"weapons/ric5.wav",
|
||||
};
|
||||
|
||||
const char *cl_explode_sounds[] =
|
||||
{
|
||||
"weapons/explode3.wav",
|
||||
"weapons/explode4.wav",
|
||||
"weapons/explode5.wav",
|
||||
};
|
||||
|
||||
/*
|
||||
================
|
||||
CL_LoadClientSprites
|
||||
|
@ -55,14 +97,91 @@ INTERNAL RESOURCE
|
|||
*/
|
||||
void CL_LoadClientSprites( void )
|
||||
{
|
||||
cl_sprite_muzzleflash[0] = CL_LoadClientSprite( "sprites/muzzleflash1.spr" );
|
||||
cl_sprite_muzzleflash[1] = CL_LoadClientSprite( "sprites/muzzleflash2.spr" );
|
||||
cl_sprite_muzzleflash[2] = CL_LoadClientSprite( "sprites/muzzleflash3.spr" );
|
||||
cl_sprite_muzzleflash[0] = CL_LoadClientSprite( cl_default_sprites[0] );
|
||||
cl_sprite_muzzleflash[1] = CL_LoadClientSprite( cl_default_sprites[1] );
|
||||
cl_sprite_muzzleflash[2] = CL_LoadClientSprite( cl_default_sprites[2] );
|
||||
|
||||
cl_sprite_dot = CL_LoadClientSprite( "sprites/dot.spr" );
|
||||
cl_sprite_glow = CL_LoadClientSprite( "sprites/animglow01.spr" );
|
||||
cl_sprite_ricochet = CL_LoadClientSprite( "sprites/richo1.spr" );
|
||||
cl_sprite_shell = CL_LoadClientSprite( "sprites/shellchrome.spr" );
|
||||
cl_sprite_dot = CL_LoadClientSprite( cl_default_sprites[3] );
|
||||
cl_sprite_glow = CL_LoadClientSprite( cl_default_sprites[4] );
|
||||
cl_sprite_ricochet = CL_LoadClientSprite( cl_default_sprites[5] );
|
||||
cl_sprite_shell = CL_LoadClientSprite( cl_default_sprites[6] );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_AddClientResource
|
||||
|
||||
add client-side resource to list
|
||||
================
|
||||
*/
|
||||
void CL_AddClientResource( const char *filename, int type )
|
||||
{
|
||||
resource_t *pResource;
|
||||
|
||||
pResource = Mem_Alloc( cls.mempool, sizeof( resource_t ));
|
||||
|
||||
Q_strncpy( pResource->szFileName, filename, sizeof( pResource->szFileName ));
|
||||
pResource->type = type;
|
||||
pResource->nIndex = -1; // client resource marker
|
||||
pResource->nDownloadSize = 1;
|
||||
pResource->ucFlags |= RES_WASMISSING;
|
||||
|
||||
CL_AddToResourceList( pResource, &cl.resourcesneeded );
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
CL_AddClientResources
|
||||
|
||||
client resources not precached by server
|
||||
================
|
||||
*/
|
||||
void CL_AddClientResources( void )
|
||||
{
|
||||
char filepath[MAX_QPATH];
|
||||
int i;
|
||||
|
||||
// check sprites first
|
||||
for( i = 0; i < ARRAYSIZE( cl_default_sprites ); i++ )
|
||||
{
|
||||
if( !FS_FileExists( cl_default_sprites[i], false ))
|
||||
CL_AddClientResource( cl_default_sprites[i], t_model );
|
||||
}
|
||||
|
||||
// then check sounds
|
||||
for( i = 0; i < ARRAYSIZE( cl_player_shell_sounds ); i++ )
|
||||
{
|
||||
Q_snprintf( filepath, sizeof( filepath ), "%s%s", DEFAULT_SOUNDPATH, cl_player_shell_sounds[i] );
|
||||
|
||||
if( !FS_FileExists( filepath, false ))
|
||||
CL_AddClientResource( cl_player_shell_sounds[i], t_sound );
|
||||
}
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( cl_weapon_shell_sounds ); i++ )
|
||||
{
|
||||
Q_snprintf( filepath, sizeof( filepath ), "%s%s", DEFAULT_SOUNDPATH, cl_weapon_shell_sounds[i] );
|
||||
|
||||
if( !FS_FileExists( filepath, false ))
|
||||
CL_AddClientResource( cl_weapon_shell_sounds[i], t_sound );
|
||||
}
|
||||
|
||||
for( i = 0; i < ARRAYSIZE( cl_explode_sounds ); i++ )
|
||||
{
|
||||
Q_snprintf( filepath, sizeof( filepath ), "%s%s", DEFAULT_SOUNDPATH, cl_explode_sounds[i] );
|
||||
|
||||
if( !FS_FileExists( filepath, false ))
|
||||
CL_AddClientResource( cl_explode_sounds[i], t_sound );
|
||||
}
|
||||
|
||||
#if 0 // ric sounds was precached by server-side
|
||||
for( i = 0; i < ARRAYSIZE( cl_ricochet_sounds ); i++ )
|
||||
{
|
||||
Q_snprintf( filepath, sizeof( filepath ), "%s%s", DEFAULT_SOUNDPATH, cl_ricochet_sounds[i] );
|
||||
|
||||
if( !FS_FileExists( filepath, false ))
|
||||
CL_AddClientResource( cl_ricochet_sounds[i], t_sound );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -311,15 +430,15 @@ void CL_TempEntPlaySound( TEMPENTITY *pTemp, float damp )
|
|||
Q_snprintf( soundname, sizeof( soundname ), "debris/wood%i.wav", COM_RandomLong( 1, 4 ));
|
||||
break;
|
||||
case BOUNCE_SHRAP:
|
||||
Q_snprintf( soundname, sizeof( soundname ), "weapons/ric%i.wav", COM_RandomLong( 1, 5 ));
|
||||
Q_snprintf( soundname, sizeof( soundname ), "%s", cl_ricochet_sounds[COM_RandomLong( 0, 4 )] );
|
||||
break;
|
||||
case BOUNCE_SHOTSHELL:
|
||||
Q_snprintf( soundname, sizeof( soundname ), "weapons/sshell%i.wav", COM_RandomLong( 1, 3 ));
|
||||
Q_snprintf( soundname, sizeof( soundname ), "%s", cl_weapon_shell_sounds[COM_RandomLong( 0, 2 )] );
|
||||
isshellcasing = true; // shell casings have different playback parameters
|
||||
fvol = 0.5f;
|
||||
break;
|
||||
case BOUNCE_SHELL:
|
||||
Q_snprintf( soundname, sizeof( soundname ), "player/pl_shell%i.wav", COM_RandomLong( 1, 3 ));
|
||||
Q_snprintf( soundname, sizeof( soundname ), "%s", cl_player_shell_sounds[COM_RandomLong( 0, 2 )] );
|
||||
isshellcasing = true; // shell casings have different playback parameters
|
||||
break;
|
||||
case BOUNCE_CONCRETE:
|
||||
|
@ -1518,7 +1637,7 @@ void R_RicochetSound( const vec3_t pos )
|
|||
char soundpath[32];
|
||||
sound_t handle;
|
||||
|
||||
Q_snprintf( soundpath, sizeof( soundpath ), "weapons/ric%i.wav", COM_RandomLong( 1, 5 ));
|
||||
Q_snprintf( soundpath, sizeof( soundpath ), "%s", cl_ricochet_sounds[COM_RandomLong( 0, 4 )] );
|
||||
handle = S_RegisterSound( soundpath );
|
||||
|
||||
S_StartSound( pos, 0, CHAN_AUTO, handle, fvol, ATTN_NORM, iPitch, 0 );
|
||||
|
@ -1668,7 +1787,7 @@ void R_Explosion( vec3_t pos, int model, float scale, float framerate, int flags
|
|||
|
||||
if( !FBitSet( flags, TE_EXPLFLAG_NOSOUND ))
|
||||
{
|
||||
hSound = S_RegisterSound( va( "weapons/explode%i.wav", COM_RandomLong( 3, 5 )));
|
||||
hSound = S_RegisterSound( va( "%s", cl_explode_sounds[COM_RandomLong( 0, 3 )] ));
|
||||
S_StartSound( pos, 0, CHAN_STATIC, hSound, VOL_NORM, 0.3f, PITCH_NORM, 0 );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -702,9 +702,6 @@ void CL_DecayLights( void );
|
|||
|
||||
//=================================================
|
||||
|
||||
void CL_PrepVideo( void );
|
||||
void CL_PrepSound( void );
|
||||
|
||||
//
|
||||
// cl_cmds.c
|
||||
//
|
||||
|
@ -939,6 +936,7 @@ void CL_FireCustomDecal( int textureIndex, int entityIndex, int modelIndex, floa
|
|||
void CL_DecalShoot( int textureIndex, int entityIndex, int modelIndex, float *pos, int flags );
|
||||
void CL_PlayerDecal( int textureIndex, int entityIndex, float *pos );
|
||||
void R_FreeDeadParticles( struct particle_s **ppparticles );
|
||||
void CL_AddClientResources( void );
|
||||
int CL_FxBlend( cl_entity_t *e );
|
||||
void CL_InitParticles( void );
|
||||
void CL_ClearParticles( void );
|
||||
|
|
|
@ -338,6 +338,7 @@ typedef struct host_parm_s
|
|||
byte *mempool; // static mempool for misc allocations
|
||||
string finalmsg; // server shutdown final message
|
||||
string downloadfile; // filename to be downloading
|
||||
int downloadcount; // how many files remain to downloading
|
||||
host_redirect_t rd; // remote console
|
||||
|
||||
// command line parms
|
||||
|
@ -699,7 +700,7 @@ void COM_InitHostState( void );
|
|||
void COM_NewGame( char const *pMapName );
|
||||
void COM_LoadLevel( char const *pMapName, qboolean background );
|
||||
void COM_LoadGame( char const *pSaveFileName );
|
||||
void COM_ChangeLevel( char const *pNewLevel, char const *pLandmarkName );
|
||||
void COM_ChangeLevel( char const *pNewLevel, char const *pLandmarkName, qboolean background );
|
||||
void COM_Frame( float time );
|
||||
|
||||
/*
|
||||
|
|
|
@ -1902,19 +1902,23 @@ Draws the debug messages (not passed to console history)
|
|||
*/
|
||||
void Con_DrawDebug( void )
|
||||
{
|
||||
int x, y, stringLen;
|
||||
string dlstring;
|
||||
int charH;
|
||||
static double timeStart;
|
||||
string dlstring;
|
||||
int x, y;
|
||||
|
||||
if( scr_download->value != -1.0f )
|
||||
{
|
||||
Q_snprintf( dlstring, sizeof( dlstring ), "Downloading: ^2%s^7 ", host.downloadfile );
|
||||
Con_DrawStringLen( dlstring, &stringLen, &charH );
|
||||
Q_snprintf( dlstring, sizeof( dlstring ), "Downloading: ^2%s^7 %5.1f%%", host.downloadfile, scr_download->value );
|
||||
x = glState.width - stringLen;
|
||||
y = charH * 1.05f;
|
||||
Q_snprintf( dlstring, sizeof( dlstring ), "Downloading [%d remaining]: ^2%s^7 %5.1f%%",
|
||||
host.downloadcount, host.downloadfile, scr_download->value, Sys_DoubleTime() - timeStart );
|
||||
x = glState.width - 400;
|
||||
y = con.curFont->charHeight * 1.05f;
|
||||
Con_DrawString( x, y, dlstring, g_color_table[7] );
|
||||
}
|
||||
else
|
||||
{
|
||||
timeStart = Sys_DoubleTime();
|
||||
}
|
||||
|
||||
if( !host_developer.value || Cvar_VariableInteger( "cl_background" ) || Cvar_VariableInteger( "sv_background" ))
|
||||
return;
|
||||
|
||||
|
@ -2241,10 +2245,6 @@ void Con_RunConsole( void )
|
|||
}
|
||||
else con.showlines = 0; // none visible
|
||||
|
||||
// HACKHACK: don't accumulate frametime
|
||||
if( cls.state < ca_active || cl.first_frame )
|
||||
host.realframetime = 0.0f;
|
||||
|
||||
lines_per_frame = fabs( scr_conspeed->value ) * host.realframetime;
|
||||
|
||||
if( con.showlines < con.vislines )
|
||||
|
|
|
@ -2381,9 +2381,9 @@ return size of file in bytes
|
|||
*/
|
||||
long FS_FileSize( const char *filename, qboolean gamedironly )
|
||||
{
|
||||
file_t *fp;
|
||||
int length = -1; // in case file was missed
|
||||
|
||||
file_t *fp;
|
||||
|
||||
fp = FS_Open( filename, "rb", gamedironly );
|
||||
|
||||
if( fp )
|
||||
|
|
|
@ -73,12 +73,13 @@ void COM_LoadGame( char const *pMapName )
|
|||
GameState->loadGame = true;
|
||||
}
|
||||
|
||||
void COM_ChangeLevel( char const *pNewLevel, char const *pLandmarkName )
|
||||
void COM_ChangeLevel( char const *pNewLevel, char const *pLandmarkName, qboolean background )
|
||||
{
|
||||
if( GameState->nextstate != STATE_RUNFRAME )
|
||||
return;
|
||||
|
||||
Q_strncpy( GameState->levelName, pNewLevel, sizeof( GameState->levelName ));
|
||||
GameState->backgroundMap = background;
|
||||
|
||||
if( COM_CheckString( pLandmarkName ))
|
||||
{
|
||||
|
@ -128,7 +129,7 @@ void Host_RunFrame( float time )
|
|||
Host_SetState( STATE_GAME_SHUTDOWN, false );
|
||||
break;
|
||||
case STATE_CHANGELEVEL:
|
||||
SCR_BeginLoadingPlaque( false );
|
||||
SCR_BeginLoadingPlaque( GameState->backgroundMap );
|
||||
Host_SetState( GameState->nextstate, true );
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -178,6 +178,7 @@ void Mod_PrintWorldStats_f( void );
|
|||
void Mod_InitStudioAPI( void );
|
||||
void Mod_InitStudioHull( void );
|
||||
void Mod_ResetStudioAPI( void );
|
||||
const char *Mod_StudioTexName( const char *modname );
|
||||
qboolean Mod_GetStudioBounds( const char *name, vec3_t mins, vec3_t maxs );
|
||||
void Mod_StudioGetAttachment( const edict_t *e, int iAttachment, float *org, float *ang );
|
||||
void Mod_GetBonePosition( const edict_t *e, int iBone, float *org, float *ang );
|
||||
|
|
|
@ -727,11 +727,11 @@ Mod_StudioTexName
|
|||
extract texture filename from modelname
|
||||
===============
|
||||
*/
|
||||
const char *Mod_StudioTexName( model_t *mod )
|
||||
const char *Mod_StudioTexName( const char *modname )
|
||||
{
|
||||
static char texname[MAX_QPATH];
|
||||
|
||||
Q_strncpy( texname, mod->name, sizeof( texname ));
|
||||
Q_strncpy( texname, modname, sizeof( texname ));
|
||||
COM_StripExtension( texname );
|
||||
Q_strncat( texname, "T.mdl", sizeof( texname ));
|
||||
|
||||
|
@ -813,7 +813,7 @@ void Mod_LoadStudioModel( model_t *mod, const void *buffer, qboolean *loaded )
|
|||
void *buffer2 = NULL;
|
||||
size_t size1, size2;
|
||||
|
||||
buffer2 = FS_LoadFile( Mod_StudioTexName( mod ), NULL, false );
|
||||
buffer2 = FS_LoadFile( Mod_StudioTexName( mod->name ), NULL, false );
|
||||
thdr = R_StudioLoadHeader( mod, buffer2 );
|
||||
|
||||
if( !thdr )
|
||||
|
|
|
@ -54,9 +54,9 @@ void MSG_InitMasks( void )
|
|||
|
||||
void MSG_InitExt( sizebuf_t *sb, const char *pDebugName, void *pData, int nBytes, int nMaxBits )
|
||||
{
|
||||
sb->pDebugName = pDebugName;
|
||||
|
||||
MSG_StartWriting( sb, pData, nBytes, 0, nMaxBits );
|
||||
|
||||
sb->pDebugName = pDebugName;
|
||||
}
|
||||
|
||||
void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, int nBits )
|
||||
|
@ -64,6 +64,7 @@ void MSG_StartWriting( sizebuf_t *sb, void *pData, int nBytes, int iStartBit, in
|
|||
// make sure it's dword aligned and padded.
|
||||
Assert(((dword)pData & 3 ) == 0 );
|
||||
|
||||
sb->pDebugName = "Unnamed";
|
||||
sb->pData = (byte *)pData;
|
||||
|
||||
if( nBits == -1 )
|
||||
|
@ -654,7 +655,7 @@ void MSG_ExciseBits( sizebuf_t *sb, int startbit, int bitstoremove )
|
|||
int remaining_to_end = sb->nDataBits - endbit;
|
||||
sizebuf_t temp;
|
||||
|
||||
MSG_StartWriting( &temp, sb->pData, sb->nDataBits << 3, startbit, -1 );
|
||||
MSG_StartWriting( &temp, sb->pData, MSG_GetMaxBytes( sb ), startbit, -1 );
|
||||
MSG_SeekToBit( sb, endbit );
|
||||
|
||||
for( i = 0; i < remaining_to_end; i++ )
|
||||
|
|
|
@ -28,8 +28,10 @@ GNU General Public License for more details.
|
|||
#define FLOW_AVG ( 2.0 / 3.0 ) // how fast to converge flow estimates
|
||||
#define FLOW_INTERVAL 0.1 // don't compute more often than this
|
||||
|
||||
#define MAX_RELIABLE_PAYLOAD 1200 // biggest packet that has frag and or reliable data
|
||||
#define MAX_RESEND_PAYLOAD 1400
|
||||
#define MAX_RELIABLE_PAYLOAD 32768 // biggest packet that has frag and or reliable data
|
||||
#define MAX_RELIABLE_PAYLOAD_BITS (MAX_RELIABLE_PAYLOAD<<3)
|
||||
#define MAX_RESEND_PAYLOAD 36000
|
||||
#define MAX_RESEND_PAYLOAD_BITS (MAX_RESEND_PAYLOAD<<3)
|
||||
|
||||
// forward declarations
|
||||
void Netchan_FlushIncoming( netchan_t *chan, int stream );
|
||||
|
@ -502,7 +504,7 @@ void Netchan_FragSend( netchan_t *chan )
|
|||
// already something queued up, just leave in waitlist
|
||||
if( chan->fragbufs[i] ) continue;
|
||||
|
||||
wait = chan->waitlist[i] ;
|
||||
wait = chan->waitlist[i];
|
||||
|
||||
// nothing to queue?
|
||||
if( !wait ) continue;
|
||||
|
@ -587,6 +589,8 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
|
|||
chunksize = chan->pfnBlockSize( chan->client );
|
||||
else chunksize = FRAGMENT_SV2CL_MAX_SIZE;
|
||||
|
||||
chunksize = 8192;
|
||||
|
||||
wait = (fragbufwaiting_t *)Mem_Alloc( net_mempool, sizeof( fragbufwaiting_t ));
|
||||
|
||||
remaining = MSG_GetNumBitsWritten( msg );
|
||||
|
@ -609,8 +613,8 @@ static void Netchan_CreateFragments_( netchan_t *chan, sizebuf_t *msg )
|
|||
|
||||
MSG_StartReading( &temp, MSG_GetData( msg ), MSG_GetMaxBytes( msg ), MSG_GetNumBitsWritten( msg ), -1 );
|
||||
MSG_SeekToBit( &temp, pos );
|
||||
MSG_ReadBits( &temp, buffer, bits );
|
||||
|
||||
MSG_ReadBits( &temp, buffer, bits );
|
||||
MSG_WriteBits( &buf->frag_message, buffer, bits );
|
||||
|
||||
Netchan_AddFragbufToTail( wait, buf );
|
||||
|
@ -718,8 +722,8 @@ void Netchan_CheckForCompletion( netchan_t *chan, int stream, int intotalbuffers
|
|||
// received final message
|
||||
if( c == intotalbuffers )
|
||||
{
|
||||
// MsgDev( D_NOTE, "\n%s: incoming is complete %i bytes waiting\n", ns_strings[chan->sock], size );
|
||||
chan->incomingready[stream] = true;
|
||||
MsgDev( D_NOTE, "\n%s: incoming is complete %i bytes waiting\n", ns_strings[chan->sock], size );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -822,7 +826,7 @@ int Netchan_CreateFileFragments( netchan_t *chan, const char *filename )
|
|||
chunksize = chan->pfnBlockSize( chan->client );
|
||||
else chunksize = FRAGMENT_SV2CL_MAX_SIZE;
|
||||
filesize = FS_FileSize( filename, false );
|
||||
|
||||
chunksize = 32768;
|
||||
if( filesize <= 0 )
|
||||
{
|
||||
MsgDev( D_WARN, "Unable to open %s for transfer\n", filename );
|
||||
|
@ -1092,7 +1096,6 @@ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg )
|
|||
else
|
||||
{
|
||||
// g-cont. it's will be stored downloaded files directly into game folder
|
||||
Con_Printf( "write file: %s\n", filename );
|
||||
FS_WriteFile( filename, buffer, pos );
|
||||
Mem_Free( buffer );
|
||||
}
|
||||
|
@ -1113,6 +1116,8 @@ qboolean Netchan_Validate( netchan_t *chan, sizebuf_t *sb, qboolean *frag_messag
|
|||
int i, buffer, offset;
|
||||
int count, length;
|
||||
|
||||
return true;
|
||||
|
||||
for( i = 0; i < MAX_STREAMS; i++ )
|
||||
{
|
||||
if( !frag_message[i] )
|
||||
|
@ -1152,8 +1157,11 @@ void Netchan_UpdateProgress( netchan_t *chan )
|
|||
int total = 0;
|
||||
float bestpercent = 0.0;
|
||||
|
||||
scr_download->value = -1.0f;
|
||||
host.downloadfile[0] = '\0';
|
||||
if( host.downloadcount == 0 )
|
||||
{
|
||||
scr_download->value = -1.0f;
|
||||
host.downloadfile[0] = '\0';
|
||||
}
|
||||
|
||||
// do show slider for file downloads.
|
||||
if( !chan->incomingbufs[FRAG_FILE_STREAM] )
|
||||
|
@ -1295,7 +1303,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
|||
send_from_regular = false;
|
||||
|
||||
// if the reliable buffer has gotten too big, queue it at the end of everything and clear out buffer
|
||||
if( MSG_GetNumBytesWritten( &chan->message ) > MAX_RELIABLE_PAYLOAD )
|
||||
if( MSG_GetNumBitsWritten( &chan->message ) > MAX_RELIABLE_PAYLOAD_BITS )
|
||||
{
|
||||
Netchan_CreateFragments_( chan, &chan->message );
|
||||
MSG_Clear( &chan->message );
|
||||
|
@ -1345,7 +1353,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
|||
|
||||
if( pbuf )
|
||||
{
|
||||
fragment_size = MSG_GetNumBytesWritten( &pbuf->frag_message );
|
||||
fragment_size = MSG_GetNumBitsWritten( &pbuf->frag_message );
|
||||
|
||||
// files set size a bit differently.
|
||||
if( pbuf->isfile && !pbuf->isbuffer )
|
||||
|
@ -1355,7 +1363,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
|||
}
|
||||
|
||||
// make sure we have enought space left
|
||||
if( send_from_frag[i] && pbuf && (( chan->reliable_length + fragment_size ) < MAX_RELIABLE_PAYLOAD ))
|
||||
if( send_from_frag[i] && pbuf && (( chan->reliable_length + fragment_size ) < MAX_RELIABLE_PAYLOAD_BITS ))
|
||||
{
|
||||
sizebuf_t temp;
|
||||
|
||||
|
@ -1451,7 +1459,7 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
|||
}
|
||||
|
||||
// is there room for the unreliable payload?
|
||||
max_send_size = (MAX_RESEND_PAYLOAD << 3);
|
||||
max_send_size = MAX_RESEND_PAYLOAD_BITS;
|
||||
if( !send_resending )
|
||||
max_send_size = MSG_GetMaxBits( &send );
|
||||
|
||||
|
@ -1462,8 +1470,6 @@ void Netchan_TransmitBits( netchan_t *chan, int length, byte *data )
|
|||
// deal with packets that are too small for some networks
|
||||
if( MSG_GetNumBytesWritten( &send ) < 16 && !NET_IsLocalAddress( chan->remote_address )) // packet too small for some networks
|
||||
{
|
||||
int i;
|
||||
|
||||
// go ahead and pad a full 16 extra bytes -- this only happens during authentication / signon
|
||||
for( i = MSG_GetNumBytesWritten( &send ); i < 16; i++ )
|
||||
{
|
||||
|
|
|
@ -18,17 +18,22 @@ GNU General Public License for more details.
|
|||
#include "netchan.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
#define PORT_ANY -1
|
||||
//#define NET_USE_FRAGMENTS // disabled until revision of netchan will be done
|
||||
|
||||
#define PORT_ANY -1
|
||||
#define MAX_LOOPBACK 4
|
||||
#define MASK_LOOPBACK (MAX_LOOPBACK - 1)
|
||||
|
||||
#define MAX_ROUTEABLE_PACKET 1400
|
||||
#define SPLIT_SIZE ( MAX_ROUTEABLE_PACKET - sizeof( SPLITPACKET ))
|
||||
|
||||
#define MAX_UDP_PACKET 4010 // 9 bytes SPLITHEADER + 4000 payload?
|
||||
#define NET_MAX_FRAGMENTS 32
|
||||
|
||||
#ifdef NET_USE_FRAGMENTS
|
||||
#define MAX_UDP_PACKET 4010 // 9 bytes SPLITHEADER + 4000 payload?
|
||||
#else
|
||||
#define MAX_UDP_PACKET NET_MAX_MESSAGE
|
||||
#endif
|
||||
|
||||
// wsock32.dll exports
|
||||
static int (_stdcall *pWSACleanup)( void );
|
||||
static word (_stdcall *pNtohs)( word netshort );
|
||||
|
@ -84,7 +89,7 @@ dll_info_t winsock_dll = { "wsock32.dll", winsock_funcs, false };
|
|||
|
||||
typedef struct
|
||||
{
|
||||
byte data[NET_MAX_MESSAGE];
|
||||
byte data[MAX_INIT_MSG];
|
||||
int datalen;
|
||||
} net_loopmsg_t;
|
||||
|
||||
|
@ -977,6 +982,7 @@ Fragment long packets, send short directly
|
|||
*/
|
||||
int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, int len, int flags, const struct sockaddr *to, int tolen )
|
||||
{
|
||||
#ifdef NET_USE_FRAGMENTS
|
||||
// do we need to break this packet up?
|
||||
if( sock == NS_SERVER && len > MAX_ROUTEABLE_PACKET )
|
||||
{
|
||||
|
@ -1029,6 +1035,9 @@ int NET_SendLong( netsrc_t sock, int net_socket, const char *buf, int len, int f
|
|||
// no fragmenantion for client connection
|
||||
return pSendTo( net_socket, buf, len, flags, to, tolen );
|
||||
}
|
||||
#else
|
||||
return pSendTo( net_socket, buf, len, flags, to, tolen );
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -23,6 +23,14 @@ typedef enum
|
|||
NS_COUNT
|
||||
} netsrc_t;
|
||||
|
||||
// Max length of unreliable message
|
||||
#define MAX_DATAGRAM 4000
|
||||
|
||||
// Max length of a multicast message
|
||||
#define MAX_MULTICAST 8192 // some mods spamming for rain effect
|
||||
|
||||
#define MAX_INIT_MSG 0x20000 // max length of possible message
|
||||
|
||||
#include "netadr.h"
|
||||
|
||||
extern convar_t *net_showpackets;
|
||||
|
|
|
@ -37,16 +37,8 @@ GNU General Public License for more details.
|
|||
|
||||
// NETWORKING INFO
|
||||
|
||||
// Max length of a multicast message
|
||||
#define MAX_MULTICAST 8192 // some mods spamming for rain effect
|
||||
|
||||
// Max length of unreliable message
|
||||
#define MAX_DATAGRAM 4000
|
||||
|
||||
#define MAX_INIT_MSG 0x20000 // max length of possible message
|
||||
|
||||
// This is the packet payload without any header bytes (which are attached for actual sending)
|
||||
#define NET_MAX_PAYLOAD 3990
|
||||
#define NET_MAX_PAYLOAD MAX_INIT_MSG
|
||||
|
||||
// This is the payload plus any header info (excluding UDP header)
|
||||
|
||||
|
@ -122,7 +114,7 @@ typedef struct fragbuf_s
|
|||
struct fragbuf_s *next; // next buffer in chain
|
||||
int bufferid; // id of this buffer
|
||||
sizebuf_t frag_message; // message buffer where raw data is stored
|
||||
byte frag_message_buf[NET_MAX_PAYLOAD]; // the actual data sits here
|
||||
byte frag_message_buf[NET_MAX_MESSAGE]; // the actual data sits here
|
||||
qboolean isfile; // is this a file buffer?
|
||||
qboolean isbuffer; // is this file buffer from memory ( custom decal, etc. ).
|
||||
char filename[MAX_OSPATH]; // name of the file to save out on remote host
|
||||
|
@ -165,12 +157,12 @@ typedef struct netchan_s
|
|||
|
||||
// staging and holding areas
|
||||
sizebuf_t message;
|
||||
byte message_buf[NET_MAX_PAYLOAD];
|
||||
byte message_buf[NET_MAX_MESSAGE];
|
||||
|
||||
// reliable message buffer.
|
||||
// we keep adding to it until reliable is acknowledged. Then we clear it.
|
||||
int reliable_length;
|
||||
byte reliable_buf[NET_MAX_PAYLOAD]; // unacked reliable message (max size for loopback connection)
|
||||
byte reliable_buf[NET_MAX_MESSAGE]; // unacked reliable message (max size for loopback connection)
|
||||
|
||||
// Waiting list of buffered fragments to go onto queue.
|
||||
// Multiple outgoing buffers can be queued in succession
|
||||
|
@ -182,8 +174,8 @@ typedef struct netchan_s
|
|||
fragbuf_t *fragbufs[MAX_STREAMS]; // the current fragment being set
|
||||
int fragbufcount[MAX_STREAMS]; // the total number of fragments in this stream
|
||||
|
||||
short frag_startpos[MAX_STREAMS]; // position in outgoing buffer where frag data starts
|
||||
short frag_length[MAX_STREAMS]; // length of frag data in the buffer
|
||||
int frag_startpos[MAX_STREAMS]; // position in outgoing buffer where frag data starts
|
||||
int frag_length[MAX_STREAMS]; // length of frag data in the buffer
|
||||
|
||||
fragbuf_t *incomingbufs[MAX_STREAMS]; // incoming fragments are stored here
|
||||
qboolean incomingready[MAX_STREAMS]; // set to true when incoming data is ready
|
||||
|
|
|
@ -652,7 +652,7 @@ void SV_ClearSaveDir( void );
|
|||
void SV_SaveGame( const char *pName );
|
||||
qboolean SV_LoadGame( const char *pName );
|
||||
int SV_LoadGameState( char const *level, qboolean changelevel );
|
||||
void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char *start );
|
||||
void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char *start, qboolean background );
|
||||
void SV_LoadAdjacentEnts( const char *pOldLevel, const char *pLandmarkName );
|
||||
const char *SV_GetLatestSave( void );
|
||||
void SV_InitSaveRestore( void );
|
||||
|
|
|
@ -1488,138 +1488,6 @@ static qboolean SV_New_f( sv_client_t *cl )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_WriteModels_f
|
||||
==================
|
||||
*/
|
||||
static qboolean SV_WriteModels_f( sv_client_t *cl )
|
||||
{
|
||||
int start;
|
||||
string cmd;
|
||||
|
||||
if( cl->state != cs_connected )
|
||||
return false;
|
||||
|
||||
// handle the case of a level changing while a client was connecting
|
||||
if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount )
|
||||
{
|
||||
SV_New_f( cl );
|
||||
return true;
|
||||
}
|
||||
|
||||
start = Q_atoi( Cmd_Argv( 2 ));
|
||||
|
||||
// write a packet full of data
|
||||
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_DATAGRAM ) && start < MAX_MODELS )
|
||||
{
|
||||
if( sv.model_precache[start][0] )
|
||||
{
|
||||
MSG_BeginServerCmd( &cl->netchan.message, svc_modelindex );
|
||||
MSG_WriteUBitLong( &cl->netchan.message, start, MAX_MODEL_BITS );
|
||||
MSG_WriteString( &cl->netchan.message, sv.model_precache[start] );
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
||||
if( start == MAX_MODELS ) Q_snprintf( cmd, MAX_STRING, "cmd soundlist %i %i\n", svs.spawncount, 0 );
|
||||
else Q_snprintf( cmd, MAX_STRING, "cmd modellist %i %i\n", svs.spawncount, start );
|
||||
|
||||
// send next command
|
||||
MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext );
|
||||
MSG_WriteString( &cl->netchan.message, cmd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_WriteSounds_f
|
||||
==================
|
||||
*/
|
||||
static qboolean SV_WriteSounds_f( sv_client_t *cl )
|
||||
{
|
||||
int start;
|
||||
string cmd;
|
||||
|
||||
if( cl->state != cs_connected )
|
||||
return false;
|
||||
|
||||
// handle the case of a level changing while a client was connecting
|
||||
if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount )
|
||||
{
|
||||
SV_New_f( cl );
|
||||
return true;
|
||||
}
|
||||
|
||||
start = Q_atoi( Cmd_Argv( 2 ));
|
||||
|
||||
// write a packet full of data
|
||||
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_DATAGRAM ) && start < MAX_SOUNDS )
|
||||
{
|
||||
if( sv.sound_precache[start][0] )
|
||||
{
|
||||
MSG_BeginServerCmd( &cl->netchan.message, svc_soundindex );
|
||||
MSG_WriteUBitLong( &cl->netchan.message, start, MAX_SOUND_BITS );
|
||||
MSG_WriteString( &cl->netchan.message, sv.sound_precache[start] );
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
||||
if( start == MAX_SOUNDS ) Q_snprintf( cmd, MAX_STRING, "cmd eventlist %i %i\n", svs.spawncount, 0 );
|
||||
else Q_snprintf( cmd, MAX_STRING, "cmd soundlist %i %i\n", svs.spawncount, start );
|
||||
|
||||
// send next command
|
||||
MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext );
|
||||
MSG_WriteString( &cl->netchan.message, cmd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SV_WriteEvents_f
|
||||
==================
|
||||
*/
|
||||
static qboolean SV_WriteEvents_f( sv_client_t *cl )
|
||||
{
|
||||
int start;
|
||||
string cmd;
|
||||
|
||||
if( cl->state != cs_connected )
|
||||
return false;
|
||||
|
||||
// handle the case of a level changing while a client was connecting
|
||||
if( Q_atoi( Cmd_Argv( 1 )) != svs.spawncount )
|
||||
{
|
||||
SV_New_f( cl );
|
||||
return true;
|
||||
}
|
||||
|
||||
start = Q_atoi( Cmd_Argv( 2 ));
|
||||
|
||||
// write a packet full of data
|
||||
while(( MSG_GetNumBytesLeft( &cl->netchan.message ) > MAX_DATAGRAM ) && start < MAX_EVENTS )
|
||||
{
|
||||
if( sv.event_precache[start][0] )
|
||||
{
|
||||
MSG_BeginServerCmd( &cl->netchan.message, svc_eventindex );
|
||||
MSG_WriteUBitLong( &cl->netchan.message, start, MAX_EVENT_BITS );
|
||||
MSG_WriteString( &cl->netchan.message, sv.event_precache[start] );
|
||||
}
|
||||
start++;
|
||||
}
|
||||
|
||||
if( start == MAX_EVENTS ) Q_snprintf( cmd, MAX_STRING, "precache %i\n", svs.spawncount );
|
||||
else Q_snprintf( cmd, MAX_STRING, "cmd eventlist %i %i\n", svs.spawncount, start );
|
||||
|
||||
// send next command
|
||||
MSG_BeginServerCmd( &cl->netchan.message, svc_stufftext );
|
||||
MSG_WriteString( &cl->netchan.message, cmd );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SV_Disconnect_f
|
||||
|
@ -1951,6 +1819,13 @@ static qboolean SV_DownloadFile_f( sv_client_t *cl )
|
|||
{
|
||||
if( Netchan_CreateFileFragments( &cl->netchan, name ))
|
||||
{
|
||||
// also check the model textures
|
||||
if( !Q_stricmp( COM_FileExtension( name ), "mdl" ))
|
||||
{
|
||||
if( FS_FileExists( Mod_StudioTexName( name ), false ) > 0 )
|
||||
Netchan_CreateFileFragments( &cl->netchan, Mod_StudioTexName( name ));
|
||||
}
|
||||
|
||||
Netchan_FragSend( &cl->netchan );
|
||||
return true;
|
||||
}
|
||||
|
@ -2050,9 +1925,6 @@ ucmd_t ucmds[] =
|
|||
{ "notarget", SV_Notarget_f },
|
||||
{ "info", SV_ShowServerinfo_f },
|
||||
{ "dlfile", SV_DownloadFile_f },
|
||||
{ "modellist", SV_WriteModels_f },
|
||||
{ "soundlist", SV_WriteSounds_f },
|
||||
{ "eventlist", SV_WriteEvents_f },
|
||||
{ "disconnect", SV_Disconnect_f },
|
||||
{ "userinfo", SV_UpdateUserinfo_f },
|
||||
{ NULL, NULL }
|
||||
|
|
|
@ -1350,8 +1350,8 @@ void pfnChangeLevel( const char *level, const char *landmark )
|
|||
SV_SkipUpdates ();
|
||||
|
||||
// changelevel will be executed on a next frame
|
||||
if( smooth ) COM_ChangeLevel( mapname, landname ); // Smoothed Half-Life changelevel
|
||||
else COM_ChangeLevel( mapname, NULL ); // Classic Quake changlevel
|
||||
if( smooth ) COM_ChangeLevel( mapname, landname, sv.background ); // Smoothed Half-Life changelevel
|
||||
else COM_ChangeLevel( mapname, NULL, sv.background ); // Classic Quake changlevel
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -279,8 +279,7 @@ void SV_CreateResourceList( void )
|
|||
{
|
||||
s = sv.files_precache[i];
|
||||
if( !COM_CheckString( s )) break; // end of list
|
||||
nSize = ( svs.maxclients > 1 ) ? FS_FileSize( s, false ) : 0;
|
||||
if( nSize < 0 ) nSize = 0;
|
||||
nSize = FS_FileSize( s, false );
|
||||
SV_AddResource( t_generic, s, nSize, RES_FATALIFMISSING, i );
|
||||
}
|
||||
|
||||
|
@ -300,8 +299,7 @@ void SV_CreateResourceList( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
nSize = ( svs.maxclients > 1 ) ? FS_FileSize( va( "sound/%s", s ), false ) : 0;
|
||||
if( nSize < 0 ) nSize = 0;
|
||||
nSize = FS_FileSize( va( "sound/%s", s ), false );
|
||||
SV_AddResource( t_sound, s, nSize, 0, i );
|
||||
}
|
||||
}
|
||||
|
@ -310,8 +308,7 @@ void SV_CreateResourceList( void )
|
|||
{
|
||||
s = sv.model_precache[i];
|
||||
if( !COM_CheckString( s )) break; // end of list
|
||||
nSize = ( svs.maxclients > 1 && s[0] != '*' ) ? FS_FileSize( s, false ) : 0;
|
||||
if( nSize < 0 ) nSize = 0;
|
||||
nSize = ( s[0] != '*' ) ? FS_FileSize( s, false ) : 0;
|
||||
SV_AddResource( t_model, s, nSize, sv.model_precache_flags[i], i );
|
||||
}
|
||||
|
||||
|
@ -325,8 +322,7 @@ void SV_CreateResourceList( void )
|
|||
{
|
||||
s = sv.event_precache[i];
|
||||
if( !COM_CheckString( s )) break; // end of list
|
||||
nSize = ( svs.maxclients > 1 ) ? FS_FileSize( s, false ) : 0;
|
||||
if( nSize < 0 ) nSize = 0;
|
||||
nSize = FS_FileSize( s, false );
|
||||
SV_AddResource( t_eventscript, s, nSize, RES_FATALIFMISSING, i );
|
||||
}
|
||||
}
|
||||
|
@ -908,5 +904,5 @@ State machine exec changelevel path
|
|||
*/
|
||||
void SV_ExecChangeLevel( void )
|
||||
{
|
||||
SV_ChangeLevel( GameState->loadGame, GameState->levelName, GameState->landmarkName );
|
||||
SV_ChangeLevel( GameState->loadGame, GameState->levelName, GameState->landmarkName, GameState->backgroundMap );
|
||||
}
|
|
@ -32,9 +32,6 @@ void SV_ClearPhysEnts( void )
|
|||
|
||||
qboolean SV_PlayerIsFrozen( edict_t *pClient )
|
||||
{
|
||||
if( sv.background )
|
||||
return true; // always freeze client on background
|
||||
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -1922,7 +1922,7 @@ void SV_LoadAdjacentEnts( const char *pOldLevel, const char *pLandmarkName )
|
|||
SV_ChangeLevel
|
||||
=============
|
||||
*/
|
||||
void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char *start )
|
||||
void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char *start, qboolean background )
|
||||
{
|
||||
char level[MAX_QPATH];
|
||||
char oldlevel[MAX_QPATH];
|
||||
|
@ -1958,7 +1958,7 @@ void SV_ChangeLevel( qboolean loadfromsavedgame, const char *mapname, const char
|
|||
SV_FinalMessage( "", true );
|
||||
SV_DeactivateServer ();
|
||||
|
||||
if( !SV_SpawnServer( level, startspot, false ))
|
||||
if( !SV_SpawnServer( level, startspot, background ))
|
||||
return; // ???
|
||||
|
||||
if( loadfromsavedgame )
|
||||
|
|
Reference in New Issue