14 Jun 2018
This commit is contained in:
parent
9a7f86278a
commit
844e5842b7
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
cl_debug.c - server message debugging
|
||||
Copyright (C) 2018 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "client.h"
|
||||
#include "net_encode.h"
|
||||
#include "particledef.h"
|
||||
#include "gl_local.h"
|
||||
#include "cl_tent.h"
|
||||
#include "shake.h"
|
||||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
|
||||
#define MSG_COUNT 32 // last 32 messages parsed
|
||||
#define MSG_MASK (MSG_COUNT - 1)
|
||||
|
||||
const char *svc_strings[svc_lastmsg+1] =
|
||||
{
|
||||
"svc_bad",
|
||||
"svc_nop",
|
||||
"svc_disconnect",
|
||||
"svc_event",
|
||||
"svc_changing",
|
||||
"svc_setview",
|
||||
"svc_sound",
|
||||
"svc_time",
|
||||
"svc_print",
|
||||
"svc_stufftext",
|
||||
"svc_setangle",
|
||||
"svc_serverdata",
|
||||
"svc_lightstyle",
|
||||
"svc_updateuserinfo",
|
||||
"svc_deltatable",
|
||||
"svc_clientdata",
|
||||
"svc_resource",
|
||||
"svc_pings",
|
||||
"svc_particle",
|
||||
"svc_restoresound",
|
||||
"svc_spawnstatic",
|
||||
"svc_event_reliable",
|
||||
"svc_spawnbaseline",
|
||||
"svc_temp_entity",
|
||||
"svc_setpause",
|
||||
"svc_signonnum",
|
||||
"svc_centerprint",
|
||||
"svc_unused27",
|
||||
"svc_unused28",
|
||||
"svc_unused29",
|
||||
"svc_intermission",
|
||||
"svc_finale",
|
||||
"svc_cdtrack",
|
||||
"svc_restore",
|
||||
"svc_cutscene",
|
||||
"svc_weaponanim",
|
||||
"svc_bspdecal",
|
||||
"svc_roomtype",
|
||||
"svc_addangle",
|
||||
"svc_usermessage",
|
||||
"svc_packetentities",
|
||||
"svc_deltapacketentities",
|
||||
"svc_choke",
|
||||
"svc_resourcelist",
|
||||
"svc_deltamovevars",
|
||||
"svc_resourcerequest",
|
||||
"svc_customization",
|
||||
"svc_crosshairangle",
|
||||
"svc_soundfade",
|
||||
"svc_filetxferfailed",
|
||||
"svc_hltv",
|
||||
"svc_director",
|
||||
"svc_voiceinit",
|
||||
"svc_voicedata",
|
||||
"svc_unused54",
|
||||
"svc_unused55",
|
||||
"svc_resourcelocation",
|
||||
"svc_querycvarvalue",
|
||||
"svc_querycvarvalue2",
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int command;
|
||||
int starting_offset;
|
||||
int frame_number;
|
||||
} oldcmd_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
oldcmd_t oldcmd[MSG_COUNT];
|
||||
int currentcmd;
|
||||
qboolean parsing;
|
||||
} msg_debug_t;
|
||||
|
||||
static msg_debug_t cls_message_debug;
|
||||
|
||||
const char *CL_MsgInfo( int cmd )
|
||||
{
|
||||
static string sz;
|
||||
|
||||
Q_strcpy( sz, "???" );
|
||||
|
||||
if( cmd >= 0 && cmd <= svc_lastmsg )
|
||||
{
|
||||
// get engine message name
|
||||
Q_strncpy( sz, svc_strings[cmd], sizeof( sz ));
|
||||
}
|
||||
else if( cmd > svc_lastmsg && cmd <= ( svc_lastmsg + MAX_USER_MESSAGES ))
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < MAX_USER_MESSAGES; i++ )
|
||||
{
|
||||
if( clgame.msg[i].number == cmd )
|
||||
{
|
||||
Q_strncpy( sz, clgame.msg[i].name, sizeof( sz ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_Parse_Debug
|
||||
|
||||
enable message debugging
|
||||
=====================
|
||||
*/
|
||||
void CL_Parse_Debug( qboolean enable )
|
||||
{
|
||||
cls_message_debug.parsing = enable;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_Parse_RecordCommand
|
||||
|
||||
record new message params into debug buffer
|
||||
=====================
|
||||
*/
|
||||
void CL_Parse_RecordCommand( int cmd, int startoffset )
|
||||
{
|
||||
int slot;
|
||||
|
||||
if( cmd == svc_nop ) return;
|
||||
|
||||
slot = ( cls_message_debug.currentcmd++ & MSG_MASK );
|
||||
cls_message_debug.oldcmd[slot].command = cmd;
|
||||
cls_message_debug.oldcmd[slot].starting_offset = startoffset;
|
||||
cls_message_debug.oldcmd[slot].frame_number = host.framecount;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ResetFrame
|
||||
=====================
|
||||
*/
|
||||
void CL_ResetFrame( frame_t *frame )
|
||||
{
|
||||
memset( &frame->graphdata, 0, sizeof( netbandwidthgraph_t ));
|
||||
frame->receivedtime = host.realtime;
|
||||
frame->valid = true;
|
||||
frame->choked = false;
|
||||
frame->latency = 0.0;
|
||||
frame->time = cl.mtime[0];
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_WriteErrorMessage
|
||||
|
||||
write net_message into buffer.dat for debugging
|
||||
=====================
|
||||
*/
|
||||
static void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
|
||||
{
|
||||
const char *buffer_file = "buffer.dat";
|
||||
file_t *fp;
|
||||
|
||||
fp = FS_Open( buffer_file, "wb", false );
|
||||
if( !fp ) return;
|
||||
|
||||
FS_Write( fp, &cls.starting_count, sizeof( int ));
|
||||
FS_Write( fp, ¤t_count, sizeof( int ));
|
||||
FS_Write( fp, MSG_GetData( msg ), MSG_GetMaxBytes( msg ));
|
||||
FS_Close( fp );
|
||||
|
||||
Con_Printf( "Wrote erroneous message to %s\n", buffer_file );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_WriteMessageHistory
|
||||
|
||||
list last 32 messages for debugging net troubleshooting
|
||||
=====================
|
||||
*/
|
||||
void CL_WriteMessageHistory( void )
|
||||
{
|
||||
oldcmd_t *old, *failcommand;
|
||||
sizebuf_t *msg = &net_message;
|
||||
int i, thecmd;
|
||||
|
||||
if( !cls.initialized || cls.state == ca_disconnected )
|
||||
return;
|
||||
|
||||
if( !cls_message_debug.parsing )
|
||||
return;
|
||||
|
||||
Con_Printf( "Last %i messages parsed.\n", MSG_COUNT );
|
||||
|
||||
// finish here
|
||||
thecmd = cls_message_debug.currentcmd - 1;
|
||||
thecmd -= ( MSG_COUNT - 1 ); // back up to here
|
||||
|
||||
for( i = 0; i < MSG_COUNT - 1; i++ )
|
||||
{
|
||||
thecmd &= MSG_MASK;
|
||||
old = &cls_message_debug.oldcmd[thecmd];
|
||||
Con_Printf( "%i %04i %s\n", old->frame_number, old->starting_offset, CL_MsgInfo( old->command ));
|
||||
thecmd++;
|
||||
}
|
||||
|
||||
failcommand = &cls_message_debug.oldcmd[thecmd];
|
||||
Con_Printf( "BAD: %3i:%s\n", MSG_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command ));
|
||||
if( host_developer.value >= DEV_EXTENDED )
|
||||
CL_WriteErrorMessage( MSG_GetNumBytesRead( msg ) - 1, msg );
|
||||
cls_message_debug.parsing = false;
|
||||
}
|
|
@ -626,6 +626,74 @@ void CL_ReadDemoSequence( qboolean discard )
|
|||
cls.netchan.last_reliable_sequence = last_reliable_sequence;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DemoStartPlayback
|
||||
=================
|
||||
*/
|
||||
void CL_DemoStartPlayback( int mode )
|
||||
{
|
||||
if( cls.changedemo )
|
||||
{
|
||||
S_StopAllSounds( true );
|
||||
SCR_BeginLoadingPlaque( false );
|
||||
|
||||
CL_ClearState ();
|
||||
CL_InitEdicts (); // re-arrange edicts
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: at this point demo is still valid
|
||||
CL_Disconnect();
|
||||
Host_ShutdownServer();
|
||||
|
||||
Con_FastClose();
|
||||
UI_SetActiveMenu( false );
|
||||
}
|
||||
|
||||
cls.demoplayback = mode;
|
||||
cls.state = ca_connected;
|
||||
cl.background = (cls.demonum != -1) ? true : false;
|
||||
cls.spectator = false;
|
||||
cls.signon = 0;
|
||||
|
||||
demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message
|
||||
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize );
|
||||
|
||||
memset( demo.cmds, 0, sizeof( demo.cmds ));
|
||||
demo.angle_position = 1;
|
||||
demo.framecount = 0;
|
||||
cls.lastoutgoingcommand = -1;
|
||||
cls.nextcmdtime = host.realtime;
|
||||
cl.last_command_ack = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_PlayDemoQuake
|
||||
=================
|
||||
*/
|
||||
void CL_PlayDemoQuake( const char *demoname )
|
||||
{
|
||||
int c, neg = false;
|
||||
|
||||
cls.demofile = FS_Open( demoname, "rb", true );
|
||||
Q_strncpy( cls.demoname, demoname, sizeof( cls.demoname ));
|
||||
Q_strncpy( gameui.globals->demoname, demoname, sizeof( gameui.globals->demoname ));
|
||||
demo.header.host_fps = host_maxfps->value;
|
||||
cls.forcetrack = 0;
|
||||
|
||||
while(( c = FS_Getc( cls.demofile )) != '\n' )
|
||||
{
|
||||
if( c == '-' ) neg = true;
|
||||
else cls.forcetrack = cls.forcetrack * 10 + (c - '0');
|
||||
}
|
||||
|
||||
if( neg ) cls.forcetrack = -cls.forcetrack;
|
||||
CL_DemoStartPlayback( DEMO_QUAKE1 );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DemoAborted
|
||||
|
@ -735,6 +803,94 @@ qboolean CL_ReadRawNetworkData( byte *buffer, size_t *length )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DemoReadMessageQuake
|
||||
|
||||
reads demo data and write it to client
|
||||
=================
|
||||
*/
|
||||
qboolean CL_DemoReadMessageQuake( byte *buffer, size_t *length )
|
||||
{
|
||||
int msglen = 0;
|
||||
demoangle_t *a;
|
||||
|
||||
*length = 0; // assume we fail
|
||||
|
||||
// decide if it is time to grab the next message
|
||||
if( cls.signon == SIGNONS ) // allways grab until fully connected
|
||||
{
|
||||
if( cls.timedemo )
|
||||
{
|
||||
if( host.framecount == cls.td_lastframe )
|
||||
return false; // already read this frame's message
|
||||
|
||||
cls.td_lastframe = host.framecount;
|
||||
|
||||
// if this is the second frame, grab the real td_starttime
|
||||
// so the bogus time on the first frame doesn't count
|
||||
if( host.framecount == cls.td_startframe + 1 )
|
||||
cls.td_starttime = host.realtime;
|
||||
}
|
||||
else if( cl.time <= cl.mtime[0] )
|
||||
{
|
||||
// don't need another message yet
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// get the next message
|
||||
FS_Read( cls.demofile, &msglen, sizeof( int ));
|
||||
FS_Read( cls.demofile, &cl.viewangles[0], sizeof( float ));
|
||||
FS_Read( cls.demofile, &cl.viewangles[1], sizeof( float ));
|
||||
FS_Read( cls.demofile, &cl.viewangles[2], sizeof( float ));
|
||||
cls.netchan.incoming_sequence++;
|
||||
|
||||
// make sure what interp info contain angles from different frames
|
||||
// or lerping will stop working
|
||||
if( demo.lasttime != demo.timestamp )
|
||||
{
|
||||
// select entry into circular buffer
|
||||
demo.angle_position = (demo.angle_position + 1) & ANGLE_MASK;
|
||||
a = &demo.cmds[demo.angle_position];
|
||||
|
||||
// record update
|
||||
a->starttime = demo.timestamp;
|
||||
VectorCopy( cl.viewangles, a->viewangles );
|
||||
demo.lasttime = demo.timestamp;
|
||||
}
|
||||
|
||||
if( msglen < 0 )
|
||||
{
|
||||
MsgDev( D_ERROR, "Demo message length < 0\n" );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
|
||||
if( msglen > MAX_INIT_MSG )
|
||||
{
|
||||
MsgDev( D_ERROR, "Demo message %i > %i\n", msglen, MAX_INIT_MSG );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
|
||||
if( msglen > 0 )
|
||||
{
|
||||
if( FS_Read( cls.demofile, buffer, msglen ) != msglen )
|
||||
{
|
||||
MsgDev( D_ERROR, "Error reading demo message data\n" );
|
||||
CL_DemoCompleted();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
*length = msglen;
|
||||
|
||||
if( cls.state != ca_active )
|
||||
Cbuf_Execute();
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
CL_DemoReadMessage
|
||||
|
@ -765,6 +921,9 @@ qboolean CL_DemoReadMessage( byte *buffer, size_t *length )
|
|||
return false; // paused
|
||||
}
|
||||
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
return CL_DemoReadMessageQuake( buffer, length );
|
||||
|
||||
do
|
||||
{
|
||||
qboolean bSkipMessage = false;
|
||||
|
@ -933,7 +1092,8 @@ void CL_DemoInterpolateAngles( void )
|
|||
QuaternionSlerp( q2, q1, frac, q );
|
||||
QuaternionAngle( q, cl.viewangles );
|
||||
}
|
||||
else VectorCopy( cl.cmd->viewangles, cl.viewangles );
|
||||
else if( cls.demoplayback != DEMO_QUAKE1 )
|
||||
VectorCopy( cl.cmd->viewangles, cl.viewangles );
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -976,7 +1136,8 @@ void CL_StopPlayback( void )
|
|||
cls.demofile = NULL;
|
||||
|
||||
cls.olddemonum = Q_max( -1, cls.demonum - 1 );
|
||||
Mem_Free( demo.directory.entries );
|
||||
if( demo.directory.entries != NULL )
|
||||
Mem_Free( demo.directory.entries );
|
||||
cls.td_lastframe = host.framecount;
|
||||
demo.directory.numentries = 0;
|
||||
demo.directory.entries = NULL;
|
||||
|
@ -1110,6 +1271,35 @@ qboolean CL_NextDemo( void )
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_CheckStartupDemos
|
||||
|
||||
queue demos loop after movie playing
|
||||
==================
|
||||
*/
|
||||
void CL_CheckStartupDemos( void )
|
||||
{
|
||||
if( !cls.demos_pending )
|
||||
return; // no demos in loop
|
||||
|
||||
if( cls.movienum != -1 )
|
||||
return; // wait until movies finished
|
||||
|
||||
if( GameState->nextstate != STATE_RUNFRAME || cls.demoplayback )
|
||||
{
|
||||
// commandline override
|
||||
cls.demos_pending = false;
|
||||
cls.demonum = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
// run demos loop in background mode
|
||||
Cvar_SetValue( "v_dark", 1.0f );
|
||||
cls.demonum = 0;
|
||||
CL_NextDemo ();
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CL_DemoGetName
|
||||
|
@ -1230,8 +1420,9 @@ playdemo <demoname>
|
|||
*/
|
||||
void CL_PlayDemo_f( void )
|
||||
{
|
||||
string filename;
|
||||
string demoname;
|
||||
char filename1[MAX_QPATH];
|
||||
char filename2[MAX_QPATH];
|
||||
char demoname[MAX_QPATH];
|
||||
int i;
|
||||
|
||||
if( Cmd_Argc() != 2 )
|
||||
|
@ -1251,17 +1442,24 @@ void CL_PlayDemo_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
Q_strncpy( demoname, Cmd_Argv( 1 ), sizeof( demoname ) - 1 );
|
||||
Q_snprintf( filename, sizeof( filename ), "demos/%s.dem", demoname );
|
||||
Q_strncpy( demoname, Cmd_Argv( 1 ), sizeof( demoname ));
|
||||
COM_StripExtension( demoname );
|
||||
Q_snprintf( filename1, sizeof( filename1 ), "%s.dem", demoname );
|
||||
Q_snprintf( filename2, sizeof( filename2 ), "demos/%s.dem", demoname );
|
||||
|
||||
if( !FS_FileExists( filename, true ))
|
||||
if( FS_FileExists( filename1, true ))
|
||||
{
|
||||
MsgDev( D_ERROR, "couldn't open %s\n", filename );
|
||||
CL_PlayDemoQuake( filename1 );
|
||||
return;
|
||||
}
|
||||
else if( !FS_FileExists( filename2, true ))
|
||||
{
|
||||
MsgDev( D_ERROR, "couldn't open %s\n", filename2 );
|
||||
CL_DemoAborted();
|
||||
return;
|
||||
}
|
||||
|
||||
cls.demofile = FS_Open( filename, "rb", true );
|
||||
cls.demofile = FS_Open( filename2, "rb", true );
|
||||
Q_strncpy( cls.demoname, demoname, sizeof( cls.demoname ));
|
||||
Q_strncpy( gameui.globals->demoname, demoname, sizeof( gameui.globals->demoname ));
|
||||
|
||||
|
@ -1270,7 +1468,7 @@ void CL_PlayDemo_f( void )
|
|||
|
||||
if( demo.header.id != IDEMOHEADER )
|
||||
{
|
||||
MsgDev( D_ERROR, "%s is not a demo file\n", filename );
|
||||
MsgDev( D_ERROR, "%s is not a demo file\n", demoname );
|
||||
CL_DemoAborted();
|
||||
return;
|
||||
}
|
||||
|
@ -1297,24 +1495,6 @@ void CL_PlayDemo_f( void )
|
|||
return;
|
||||
}
|
||||
|
||||
if( cls.changedemo )
|
||||
{
|
||||
S_StopAllSounds( true );
|
||||
SCR_BeginLoadingPlaque( false );
|
||||
|
||||
CL_ClearState ();
|
||||
CL_InitEdicts (); // re-arrange edicts
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: at this point demo is still valid
|
||||
CL_Disconnect();
|
||||
Host_ShutdownServer();
|
||||
|
||||
Con_FastClose();
|
||||
UI_SetActiveMenu( false );
|
||||
}
|
||||
|
||||
// allocate demo entries
|
||||
demo.directory.entries = Mem_Malloc( cls.mempool, sizeof( demoentry_t ) * demo.directory.numentries );
|
||||
|
||||
|
@ -1328,22 +1508,7 @@ void CL_PlayDemo_f( void )
|
|||
|
||||
FS_Seek( cls.demofile, demo.entry->offset, SEEK_SET );
|
||||
|
||||
cls.demoplayback = true;
|
||||
cls.state = ca_connected;
|
||||
cl.background = (cls.demonum != -1) ? true : false;
|
||||
cls.spectator = false;
|
||||
cls.signon = 0;
|
||||
|
||||
demo.starttime = CL_GetDemoPlaybackClock(); // for determining whether to read another message
|
||||
|
||||
Netchan_Setup( NS_CLIENT, &cls.netchan, net_from, Cvar_VariableInteger( "net_qport" ), NULL, CL_GetFragmentSize );
|
||||
|
||||
memset( demo.cmds, 0, sizeof( demo.cmds ));
|
||||
demo.angle_position = 1;
|
||||
demo.framecount = 0;
|
||||
cls.lastoutgoingcommand = -1;
|
||||
cls.nextcmdtime = host.realtime;
|
||||
cl.last_command_ack = -1;
|
||||
CL_DemoStartPlayback( DEMO_XASH3D );
|
||||
|
||||
// g-cont. is this need?
|
||||
Q_strncpy( cls.servername, demoname, sizeof( cls.servername ));
|
||||
|
@ -1402,15 +1567,7 @@ void CL_StartDemos_f( void )
|
|||
|
||||
for( i = 1; i < c + 1; i++ )
|
||||
Q_strncpy( cls.demos[i-1], Cmd_Argv( i ), sizeof( cls.demos[0] ));
|
||||
|
||||
if( !SV_Active() && !cls.demoplayback )
|
||||
{
|
||||
// run demos loop in background mode
|
||||
Cvar_SetValue( "v_dark", 1.0f );
|
||||
cls.demonum = 0;
|
||||
CL_NextDemo ();
|
||||
}
|
||||
else cls.demonum = -1;
|
||||
cls.demos_pending = true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1074,7 +1074,7 @@ void CL_LinkPacketEntities( frame_t *frame )
|
|||
if( ent->curstate.rendermode == kRenderNormal )
|
||||
{
|
||||
// auto 'solid' faces
|
||||
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && CL_IsQuakeCompatible( ))
|
||||
{
|
||||
ent->curstate.rendermode = kRenderTransAlpha;
|
||||
ent->curstate.renderamt = 255;
|
||||
|
|
|
@ -146,6 +146,19 @@ qboolean CL_IsBackgroundMap( void )
|
|||
return ( cl.background && !cls.demoplayback );
|
||||
}
|
||||
|
||||
qboolean CL_IsQuakeCompatible( void )
|
||||
{
|
||||
// feature set
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
return true;
|
||||
|
||||
// quake demo playing
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
char *CL_Userinfo( void )
|
||||
{
|
||||
return cls.userinfo;
|
||||
|
@ -242,14 +255,31 @@ static float CL_LerpPoint( void )
|
|||
if( f == 0.0f || cls.timedemo )
|
||||
{
|
||||
cl.time = cl.mtime[0];
|
||||
|
||||
// g-cont. probably this is redundant
|
||||
if( cls.demoplayback )
|
||||
cl.oldtime = cl.mtime[0] - cl_clientframetime();
|
||||
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
if( f > 0.1f )
|
||||
{
|
||||
// dropped packet, or start of demo
|
||||
cl.mtime[1] = cl.mtime[0] - 0.1f;
|
||||
f = 0.1f;
|
||||
}
|
||||
#if 1
|
||||
frac = (cl.time - cl.mtime[1]) / f;
|
||||
|
||||
if( frac < 0.0f )
|
||||
{
|
||||
if( frac < -0.01 )
|
||||
cl.time = cl.mtime[1];
|
||||
frac = 0.0f;
|
||||
}
|
||||
else if( frac > 1.0f )
|
||||
{
|
||||
if( frac > 1.01 )
|
||||
cl.time = cl.mtime[0];
|
||||
frac = 1.0f;
|
||||
}
|
||||
#else
|
||||
if( cl_interp->value > 0.001f )
|
||||
{
|
||||
// manual lerp value (goldsrc mode)
|
||||
|
@ -260,7 +290,7 @@ static float CL_LerpPoint( void )
|
|||
// automatic lerp (classic mode)
|
||||
frac = ( cl.time - cl.mtime[1] ) / f;
|
||||
}
|
||||
|
||||
#endif
|
||||
return frac;
|
||||
}
|
||||
|
||||
|
@ -2001,7 +2031,10 @@ void CL_ReadNetMessage( void )
|
|||
if( !cls.demoplayback && !Netchan_Process( &cls.netchan, &net_message ))
|
||||
continue; // wasn't accepted for some reason
|
||||
|
||||
CL_ParseServerMessage( &net_message, true );
|
||||
// run special handler for quake demos
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
CL_ParseQuakeMessage( &net_message, true );
|
||||
else CL_ParseServerMessage( &net_message, true );
|
||||
cl.send_reply = true;
|
||||
}
|
||||
|
||||
|
@ -2044,7 +2077,7 @@ void CL_ReadPackets( void )
|
|||
// decide the simulation time
|
||||
cl.oldtime = cl.time;
|
||||
|
||||
if( !cls.demoplayback && !cl.paused )
|
||||
if( cls.demoplayback != DEMO_XASH3D && !cl.paused )
|
||||
cl.time += host.frametime;
|
||||
|
||||
// demo time
|
||||
|
|
|
@ -23,200 +23,8 @@ GNU General Public License for more details.
|
|||
#include "hltv.h"
|
||||
#include "input.h"
|
||||
|
||||
#define MSG_COUNT 32 // last 32 messages parsed
|
||||
#define MSG_MASK (MSG_COUNT - 1)
|
||||
|
||||
int CL_UPDATE_BACKUP = SINGLEPLAYER_BACKUP;
|
||||
|
||||
const char *svc_strings[svc_lastmsg+1] =
|
||||
{
|
||||
"svc_bad",
|
||||
"svc_nop",
|
||||
"svc_disconnect",
|
||||
"svc_event",
|
||||
"svc_changing",
|
||||
"svc_setview",
|
||||
"svc_sound",
|
||||
"svc_time",
|
||||
"svc_print",
|
||||
"svc_stufftext",
|
||||
"svc_setangle",
|
||||
"svc_serverdata",
|
||||
"svc_lightstyle",
|
||||
"svc_updateuserinfo",
|
||||
"svc_deltatable",
|
||||
"svc_clientdata",
|
||||
"svc_resource",
|
||||
"svc_pings",
|
||||
"svc_particle",
|
||||
"svc_restoresound",
|
||||
"svc_spawnstatic",
|
||||
"svc_event_reliable",
|
||||
"svc_spawnbaseline",
|
||||
"svc_temp_entity",
|
||||
"svc_setpause",
|
||||
"svc_signonnum",
|
||||
"svc_centerprint",
|
||||
"svc_unused27",
|
||||
"svc_unused28",
|
||||
"svc_unused29",
|
||||
"svc_intermission",
|
||||
"svc_finale",
|
||||
"svc_cdtrack",
|
||||
"svc_restore",
|
||||
"svc_cutscene",
|
||||
"svc_weaponanim",
|
||||
"svc_bspdecal",
|
||||
"svc_roomtype",
|
||||
"svc_addangle",
|
||||
"svc_usermessage",
|
||||
"svc_packetentities",
|
||||
"svc_deltapacketentities",
|
||||
"svc_choke",
|
||||
"svc_resourcelist",
|
||||
"svc_deltamovevars",
|
||||
"svc_resourcerequest",
|
||||
"svc_customization",
|
||||
"svc_crosshairangle",
|
||||
"svc_soundfade",
|
||||
"svc_filetxferfailed",
|
||||
"svc_hltv",
|
||||
"svc_director",
|
||||
"svc_voiceinit",
|
||||
"svc_voicedata",
|
||||
"svc_unused54",
|
||||
"svc_unused55",
|
||||
"svc_resourcelocation",
|
||||
"svc_querycvarvalue",
|
||||
"svc_querycvarvalue2",
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int command;
|
||||
int starting_offset;
|
||||
int frame_number;
|
||||
} oldcmd_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
oldcmd_t oldcmd[MSG_COUNT];
|
||||
int currentcmd;
|
||||
qboolean parsing;
|
||||
} msg_debug_t;
|
||||
|
||||
static msg_debug_t cls_message_debug;
|
||||
static int starting_count;
|
||||
|
||||
const char *CL_MsgInfo( int cmd )
|
||||
{
|
||||
static string sz;
|
||||
|
||||
Q_strcpy( sz, "???" );
|
||||
|
||||
if( cmd >= 0 && cmd <= svc_lastmsg )
|
||||
{
|
||||
// get engine message name
|
||||
Q_strncpy( sz, svc_strings[cmd], sizeof( sz ));
|
||||
}
|
||||
else if( cmd > svc_lastmsg && cmd <= ( svc_lastmsg + MAX_USER_MESSAGES ))
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < MAX_USER_MESSAGES; i++ )
|
||||
{
|
||||
if( clgame.msg[i].number == cmd )
|
||||
{
|
||||
Q_strncpy( sz, clgame.msg[i].name, sizeof( sz ));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_Parse_RecordCommand
|
||||
|
||||
record new message params into debug buffer
|
||||
=====================
|
||||
*/
|
||||
void CL_Parse_RecordCommand( int cmd, int startoffset )
|
||||
{
|
||||
int slot;
|
||||
|
||||
if( cmd == svc_nop ) return;
|
||||
|
||||
slot = ( cls_message_debug.currentcmd++ & MSG_MASK );
|
||||
cls_message_debug.oldcmd[slot].command = cmd;
|
||||
cls_message_debug.oldcmd[slot].starting_offset = startoffset;
|
||||
cls_message_debug.oldcmd[slot].frame_number = host.framecount;
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_WriteErrorMessage
|
||||
|
||||
write net_message into buffer.dat for debugging
|
||||
=====================
|
||||
*/
|
||||
void CL_WriteErrorMessage( int current_count, sizebuf_t *msg )
|
||||
{
|
||||
const char *buffer_file = "buffer.dat";
|
||||
file_t *fp;
|
||||
|
||||
fp = FS_Open( buffer_file, "wb", false );
|
||||
if( !fp ) return;
|
||||
|
||||
FS_Write( fp, &starting_count, sizeof( int ));
|
||||
FS_Write( fp, ¤t_count, sizeof( int ));
|
||||
FS_Write( fp, MSG_GetData( msg ), MSG_GetMaxBytes( msg ));
|
||||
FS_Close( fp );
|
||||
|
||||
Con_Printf( "Wrote erroneous message to %s\n", buffer_file );
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_WriteMessageHistory
|
||||
|
||||
list last 32 messages for debugging net troubleshooting
|
||||
=====================
|
||||
*/
|
||||
void CL_WriteMessageHistory( void )
|
||||
{
|
||||
oldcmd_t *old, *failcommand;
|
||||
sizebuf_t *msg = &net_message;
|
||||
int i, thecmd;
|
||||
|
||||
if( !cls.initialized || cls.state == ca_disconnected )
|
||||
return;
|
||||
|
||||
if( !cls_message_debug.parsing )
|
||||
return;
|
||||
|
||||
Con_Printf( "Last %i messages parsed.\n", MSG_COUNT );
|
||||
|
||||
// finish here
|
||||
thecmd = cls_message_debug.currentcmd - 1;
|
||||
thecmd -= ( MSG_COUNT - 1 ); // back up to here
|
||||
|
||||
for( i = 0; i < MSG_COUNT - 1; i++ )
|
||||
{
|
||||
thecmd &= MSG_MASK;
|
||||
old = &cls_message_debug.oldcmd[thecmd];
|
||||
Con_Printf( "%i %04i %s\n", old->frame_number, old->starting_offset, CL_MsgInfo( old->command ));
|
||||
thecmd++;
|
||||
}
|
||||
|
||||
failcommand = &cls_message_debug.oldcmd[thecmd];
|
||||
Con_Printf( "BAD: %3i:%s\n", MSG_GetNumBytesRead( msg ) - 1, CL_MsgInfo( failcommand->command ));
|
||||
if( host_developer.value >= DEV_EXTENDED )
|
||||
CL_WriteErrorMessage( MSG_GetNumBytesRead( msg ) - 1, msg );
|
||||
cls_message_debug.parsing = false;
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
CL_UserMsgStub
|
||||
|
@ -387,6 +195,9 @@ void CL_ParseServerTime( sizebuf_t *msg )
|
|||
cl.mtime[1] = cl.mtime[0];
|
||||
cl.mtime[0] = MSG_ReadFloat( msg );
|
||||
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
return; // don't mess the time
|
||||
|
||||
if( cl.maxclients == 1 )
|
||||
cl.time = cl.mtime[0];
|
||||
|
||||
|
@ -557,7 +368,7 @@ void CL_ParseStaticEntity( sizebuf_t *msg )
|
|||
if( ent->curstate.rendermode == kRenderNormal && ent->model != NULL )
|
||||
{
|
||||
// auto 'solid' faces
|
||||
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( FBitSet( ent->model->flags, MODEL_TRANSPARENT ) && CL_IsQuakeCompatible( ))
|
||||
{
|
||||
ent->curstate.rendermode = kRenderTransAlpha;
|
||||
ent->curstate.renderamt = 255;
|
||||
|
@ -2181,21 +1992,6 @@ void CL_ParseUserMessage( sizebuf_t *msg, int svc_num )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_ResetFrame
|
||||
=====================
|
||||
*/
|
||||
void CL_ResetFrame( frame_t *frame )
|
||||
{
|
||||
memset( &frame->graphdata, 0, sizeof( netbandwidthgraph_t ));
|
||||
frame->receivedtime = host.realtime;
|
||||
frame->valid = true;
|
||||
frame->choked = false;
|
||||
frame->latency = 0.0;
|
||||
frame->time = cl.mtime[0];
|
||||
}
|
||||
|
||||
/*
|
||||
=====================================================================
|
||||
|
||||
|
@ -2216,8 +2012,8 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
int cmd, param1, param2;
|
||||
int old_background;
|
||||
|
||||
cls_message_debug.parsing = true; // begin parsing
|
||||
starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
|
||||
cls.starting_count = MSG_GetNumBytesRead( msg ); // updates each frame
|
||||
CL_Parse_Debug( true ); // begin parsing
|
||||
|
||||
if( normal_message )
|
||||
{
|
||||
|
@ -2278,7 +2074,7 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
cls.changelevel = true;
|
||||
S_StopAllSounds( true );
|
||||
|
||||
MsgDev( D_INFO, "Server changing, reconnecting\n" );
|
||||
Con_Printf( "Server changing, reconnecting\n" );
|
||||
|
||||
if( cls.demoplayback )
|
||||
{
|
||||
|
@ -2289,7 +2085,7 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
CL_ClearState ();
|
||||
CL_InitEdicts (); // re-arrange edicts
|
||||
}
|
||||
else MsgDev( D_INFO, "Server disconnected, reconnecting\n" );
|
||||
else Con_Printf( "Server disconnected, reconnecting\n" );
|
||||
|
||||
if( cls.demoplayback )
|
||||
{
|
||||
|
@ -2299,7 +2095,8 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
else
|
||||
{
|
||||
// g-cont. local client skip the challenge
|
||||
if( SV_Active()) cls.state = ca_disconnected;
|
||||
if( SV_Active( ))
|
||||
cls.state = ca_disconnected;
|
||||
else cls.state = ca_connecting;
|
||||
cl.background = old_background;
|
||||
cls.connect_time = MAX_HEARTBEAT;
|
||||
|
@ -2477,8 +2274,8 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
}
|
||||
}
|
||||
|
||||
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - starting_count;
|
||||
cls_message_debug.parsing = false; // done
|
||||
cl.frames[cl.parsecountmod].graphdata.msgbytes += MSG_GetNumBytesRead( msg ) - cls.starting_count;
|
||||
CL_Parse_Debug( false ); // done
|
||||
|
||||
// we don't know if it is ok to save a demo message until
|
||||
// after we have parsed the frame
|
||||
|
@ -2486,11 +2283,11 @@ void CL_ParseServerMessage( sizebuf_t *msg, qboolean normal_message )
|
|||
{
|
||||
if( cls.demorecording && !cls.demowaiting )
|
||||
{
|
||||
CL_WriteDemoMessage( false, starting_count, msg );
|
||||
CL_WriteDemoMessage( false, cls.starting_count, msg );
|
||||
}
|
||||
else if( cls.state != ca_active )
|
||||
{
|
||||
CL_WriteDemoMessage( true, starting_count, msg );
|
||||
CL_WriteDemoMessage( true, cls.starting_count, msg );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -115,6 +115,10 @@ qboolean CL_IsPredicted( void )
|
|||
{
|
||||
if( cl_nopred->value || cl.intermission )
|
||||
return false;
|
||||
|
||||
// never predict the quake demos
|
||||
if( cls.demoplayback == DEMO_QUAKE1 )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -721,6 +721,7 @@ void SCR_Init( void )
|
|||
// register our commands
|
||||
Cmd_AddCommand( "timerefresh", SCR_TimeRefresh_f, "turn quickly and print rendering statistcs" );
|
||||
Cmd_AddCommand( "skyname", CL_SetSky_f, "set new skybox by basename" );
|
||||
Cmd_AddCommand( "loadsky", CL_SetSky_f, "set new skybox by basename" );
|
||||
Cmd_AddCommand( "viewpos", SCR_Viewpos_f, "prints current player origin" );
|
||||
Cmd_AddCommand( "sizeup", SCR_SizeUp_f, "screen size up to 10 points" );
|
||||
Cmd_AddCommand( "sizedown", SCR_SizeDown_f, "screen size down to 10 points" );
|
||||
|
|
|
@ -151,7 +151,7 @@ void CL_AddClientResources( void )
|
|||
int i;
|
||||
|
||||
// don't request resources from localhost or in quake-compatibility mode
|
||||
if( cl.maxclients <= 1 || FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( cl.maxclients <= 1 || CL_IsQuakeCompatible( ))
|
||||
return;
|
||||
|
||||
// check sprites first
|
||||
|
@ -2808,7 +2808,7 @@ void CL_AddEntityEffects( cl_entity_t *ent )
|
|||
|
||||
if( FBitSet( ent->curstate.effects, EF_DIMLIGHT ))
|
||||
{
|
||||
if( ent->player && !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( ent->player && !CL_IsQuakeCompatible( ))
|
||||
{
|
||||
CL_UpdateFlashlight( ent );
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@ qboolean SCR_NextMovie( void )
|
|||
{
|
||||
S_StopAllSounds( true );
|
||||
SCR_StopCinematic();
|
||||
CL_CheckStartupDemos();
|
||||
return false; // don't play movies
|
||||
}
|
||||
|
||||
|
@ -56,6 +57,7 @@ qboolean SCR_NextMovie( void )
|
|||
S_StopAllSounds( true );
|
||||
SCR_StopCinematic();
|
||||
cls.movienum = -1;
|
||||
CL_CheckStartupDemos();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -90,6 +92,7 @@ void SCR_CheckStartupVids( void )
|
|||
{
|
||||
// don't run movies where we in developer-mode
|
||||
cls.movienum = -1;
|
||||
CL_CheckStartupDemos();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,13 @@ GNU General Public License for more details.
|
|||
|
||||
typedef int sound_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DEMO_INACTIVE = 0,
|
||||
DEMO_XASH3D,
|
||||
DEMO_QUAKE1
|
||||
} demo_mode;
|
||||
|
||||
//=============================================================================
|
||||
typedef struct netbandwithgraph_s
|
||||
{
|
||||
|
@ -593,6 +600,7 @@ typedef struct
|
|||
|
||||
float packet_loss;
|
||||
double packet_loss_recalc_time;
|
||||
int starting_count; // message num readed bits
|
||||
|
||||
float nextcmdtime; // when can we send the next command packet?
|
||||
int lastoutgoingcommand; // sequence number of last outgoing command
|
||||
|
@ -601,6 +609,7 @@ typedef struct
|
|||
int td_lastframe; // to meter out one message a frame
|
||||
int td_startframe; // host_framecount at start
|
||||
double td_starttime; // realtime at second frame of timedemo
|
||||
int forcetrack; // -1 = use normal cd track
|
||||
|
||||
// game images
|
||||
int pauseIcon; // draw 'paused' when game in-pause
|
||||
|
@ -630,7 +639,8 @@ typedef struct
|
|||
// demo loop control
|
||||
int demonum; // -1 = don't play demos
|
||||
int olddemonum; // restore playing
|
||||
string demos[MAX_DEMOS]; // when not playing
|
||||
char demos[MAX_DEMOS][MAX_QPATH]; // when not playing
|
||||
qboolean demos_pending;
|
||||
|
||||
// movie playlist
|
||||
int movienum;
|
||||
|
@ -738,6 +748,15 @@ void CL_RemoveFromResourceList( resource_t *pResource );
|
|||
void CL_MoveToOnHandList( resource_t *pResource );
|
||||
void CL_ClearResourceLists( void );
|
||||
|
||||
//
|
||||
// cl_debug.c
|
||||
//
|
||||
void CL_Parse_Debug( qboolean enable );
|
||||
void CL_Parse_RecordCommand( int cmd, int startoffset );
|
||||
void CL_ResetFrame( frame_t *frame );
|
||||
void CL_WriteMessageHistory( void );
|
||||
const char *CL_MsgInfo( int cmd );
|
||||
|
||||
//
|
||||
// cl_main.c
|
||||
//
|
||||
|
@ -765,8 +784,10 @@ void CL_WriteDemoMessage( qboolean startup, int start, sizebuf_t *msg );
|
|||
void CL_WriteDemoUserMessage( const byte *buffer, size_t size );
|
||||
qboolean CL_DemoReadMessage( byte *buffer, size_t *length );
|
||||
void CL_DemoInterpolateAngles( void );
|
||||
void CL_CheckStartupDemos( void );
|
||||
void CL_WriteDemoJumpTime( void );
|
||||
void CL_CloseDemoHeader( void );
|
||||
void CL_DemoCompleted( void );
|
||||
void CL_StopPlayback( void );
|
||||
void CL_StopRecord( void );
|
||||
void CL_PlayDemo_f( void );
|
||||
|
@ -776,7 +797,6 @@ void CL_Demos_f( void );
|
|||
void CL_DeleteDemo_f( void );
|
||||
void CL_Record_f( void );
|
||||
void CL_Stop_f( void );
|
||||
void CL_FreeDemo( void );
|
||||
|
||||
//
|
||||
// cl_events.c
|
||||
|
@ -847,6 +867,8 @@ void CL_StartResourceDownloading( const char *pszMessage, qboolean bCustom );
|
|||
qboolean CL_DispatchUserMessage( const char *pszName, int iSize, void *pbuf );
|
||||
qboolean CL_RequestMissingResources( void );
|
||||
void CL_RegisterResources ( sizebuf_t *msg );
|
||||
void CL_ParseViewEntity( sizebuf_t *msg );
|
||||
void CL_ParseServerTime( sizebuf_t *msg );
|
||||
|
||||
//
|
||||
// cl_scrn.c
|
||||
|
@ -908,6 +930,11 @@ void CL_PushPMStates( void );
|
|||
void CL_PopPMStates( void );
|
||||
void CL_SetUpPlayerPrediction( int dopred, int bIncludeLocalClient );
|
||||
|
||||
//
|
||||
// cl_qparse.c
|
||||
//
|
||||
void CL_ParseQuakeMessage( sizebuf_t *msg, qboolean normal_message );
|
||||
|
||||
//
|
||||
// cl_studio.c
|
||||
//
|
||||
|
@ -922,7 +949,7 @@ void CL_ResetLatchedVars( cl_entity_t *ent, qboolean full_reset );
|
|||
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_ProcessPacket( frame_t *frame );
|
||||
void CL_MoveThirdpersonCamera( void );
|
||||
qboolean CL_IsPlayerIndex( int idx );
|
||||
void CL_SetIdealPitch( void );
|
||||
|
|
|
@ -883,7 +883,7 @@ byte *GL_ApplyFilter( const byte *source, int width, int height )
|
|||
byte *out = (byte *)source;
|
||||
int i;
|
||||
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ) || glConfig.max_multisamples > 1 )
|
||||
if( CL_IsQuakeCompatible() || glConfig.max_multisamples > 1 )
|
||||
return in;
|
||||
|
||||
for( i = 0; source && i < width * height; i++, in += 4 )
|
||||
|
|
|
@ -658,7 +658,7 @@ static void R_CheckFog( void )
|
|||
int i, cnt, count;
|
||||
|
||||
// quake global fog
|
||||
if( clgame.movevars.fog_settings != 0 && FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( clgame.movevars.fog_settings != 0 && CL_IsQuakeCompatible( ))
|
||||
{
|
||||
// quake-style global fog
|
||||
RI.fogColor[0] = ((clgame.movevars.fog_settings & 0xFF000000) >> 24) / 255.0f;
|
||||
|
|
|
@ -465,9 +465,12 @@ void R_NewMap( void )
|
|||
if( v_dark->value )
|
||||
{
|
||||
screenfade_t *sf = &clgame.fade;
|
||||
float fadetime = 5.0f;
|
||||
client_textmessage_t *title;
|
||||
|
||||
title = CL_TextMessageGet( "GAMETITLE" );
|
||||
if( CL_IsQuakeCompatible( ))
|
||||
fadetime = 1.0f;
|
||||
|
||||
if( title )
|
||||
{
|
||||
|
@ -475,7 +478,7 @@ void R_NewMap( void )
|
|||
sf->fadeEnd = title->holdtime + title->fadeout;
|
||||
sf->fadeReset = title->fadeout;
|
||||
}
|
||||
else sf->fadeEnd = sf->fadeReset = 5.0f;
|
||||
else sf->fadeEnd = sf->fadeReset = fadetime;
|
||||
|
||||
sf->fadeFlags = FFADE_IN;
|
||||
sf->fader = sf->fadeg = sf->fadeb = 0;
|
||||
|
|
|
@ -1232,7 +1232,7 @@ void R_DrawTextureChains( void )
|
|||
if(( s->flags & SURF_DRAWTURB ) && clgame.movevars.wateralpha < 1.0f )
|
||||
continue; // draw translucent water later
|
||||
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ) && FBitSet( s->flags, SURF_TRANSPARENT ))
|
||||
if( CL_IsQuakeCompatible() && FBitSet( s->flags, SURF_TRANSPARENT ))
|
||||
{
|
||||
draw_alpha_surfaces = true;
|
||||
continue; // draw transparent surfaces later
|
||||
|
@ -1412,7 +1412,7 @@ void R_SetRenderMode( cl_entity_t *e )
|
|||
case kRenderTransAlpha:
|
||||
pglEnable( GL_ALPHA_TEST );
|
||||
pglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( CL_IsQuakeCompatible( ))
|
||||
{
|
||||
pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
pglColor4f( 1.0f, 1.0f, 1.0f, tr.blend );
|
||||
|
@ -1482,7 +1482,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
if( rotated ) R_RotateForEntity( e );
|
||||
else R_TranslateForEntity( e );
|
||||
|
||||
if( FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ) && FBitSet( clmodel->flags, MODEL_TRANSPARENT ))
|
||||
if( CL_IsQuakeCompatible() && FBitSet( clmodel->flags, MODEL_TRANSPARENT ))
|
||||
e->curstate.rendermode = kRenderTransAlpha;
|
||||
|
||||
e->visframe = tr.realframecount; // visible
|
||||
|
@ -1515,7 +1515,7 @@ void R_DrawBrushModel( cl_entity_t *e )
|
|||
|
||||
for( i = 0; i < clmodel->nummodelsurfaces; i++, psurf++ )
|
||||
{
|
||||
if( FBitSet( psurf->flags, SURF_DRAWTURB ) && !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( FBitSet( psurf->flags, SURF_DRAWTURB ) && !CL_IsQuakeCompatible( ))
|
||||
{
|
||||
if( psurf->plane->type != PLANE_Z && !FBitSet( e->curstate.effects, EF_WATERSIDES ))
|
||||
continue;
|
||||
|
|
|
@ -1298,7 +1298,7 @@ int S_GetCurrentDynamicSounds( soundlist_t *pout, int size )
|
|||
|
||||
looped = ( channels[i].use_loop && channels[i].sfx->cache->loopStart != -1 );
|
||||
|
||||
if( channels[i].entchannel == CHAN_STATIC && looped && !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( channels[i].entchannel == CHAN_STATIC && looped && !CL_IsQuakeCompatible())
|
||||
continue; // never serialize static looped sounds. It will be restoring in game code
|
||||
|
||||
if( channels[i].isSentence && channels[i].name[0] )
|
||||
|
@ -2014,6 +2014,23 @@ void S_Play_f( void )
|
|||
S_StartLocalSound( Cmd_Argv( 1 ), VOL_NORM, false );
|
||||
}
|
||||
|
||||
void S_Play2_f( void )
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
if( Cmd_Argc() == 1 )
|
||||
{
|
||||
Con_Printf( S_USAGE "play <soundfile>\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
while( i < Cmd_Argc( ))
|
||||
{
|
||||
S_StartLocalSound( Cmd_Argv( i ), VOL_NORM, true );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void S_PlayVol_f( void )
|
||||
{
|
||||
if( Cmd_Argc() == 1 )
|
||||
|
@ -2180,6 +2197,7 @@ qboolean S_Init( void )
|
|||
s_phs = Cvar_Get( "s_phs", "0", FCVAR_ARCHIVE, "cull sounds by PHS" );
|
||||
|
||||
Cmd_AddCommand( "play", S_Play_f, "playing a specified sound file" );
|
||||
Cmd_AddCommand( "play2", S_Play2_f, "playing a group of specified sound files" ); // nehahra stuff
|
||||
Cmd_AddCommand( "playvol", S_PlayVol_f, "playing a specified sound file with specified volume" );
|
||||
Cmd_AddCommand( "stopsound", S_StopSound_f, "stop all sounds" );
|
||||
Cmd_AddCommand( "music", S_Music_f, "starting a background track" );
|
||||
|
|
|
@ -935,6 +935,7 @@ qboolean CL_IsTimeDemo( void );
|
|||
qboolean CL_IsPlaybackDemo( void );
|
||||
qboolean CL_IsBackgroundDemo( void );
|
||||
qboolean CL_IsBackgroundMap( void );
|
||||
qboolean CL_IsQuakeCompatible( void );
|
||||
qboolean SV_Initialized( void );
|
||||
qboolean CL_LoadProgs( const char *name );
|
||||
qboolean SV_GetSaveComment( const char *savename, char *comment );
|
||||
|
|
|
@ -2333,18 +2333,18 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
|
|||
COM_DefaultExtension( dllpath, ".dll" ); // apply ext if forget
|
||||
search = FS_FindFile( dllpath, &index, false );
|
||||
|
||||
if( !search )
|
||||
if( !search && !directpath )
|
||||
{
|
||||
fs_ext_path = false;
|
||||
if( directpath ) return NULL; // direct paths fails here
|
||||
|
||||
// trying check also 'bin' folder for indirect paths
|
||||
Q_strncpy( dllpath, dllname, sizeof( dllpath ));
|
||||
search = FS_FindFile( dllpath, &index, false );
|
||||
if( !search ) return NULL; // unable to find
|
||||
if( !search ) return NULL; // unable to find
|
||||
}
|
||||
|
||||
// all done, create dll_user_t struct
|
||||
// NOTE: for libraries we not fail even if search is NULL
|
||||
// let the OS find library himself
|
||||
hInst = Mem_Calloc( host.mempool, sizeof( dll_user_t ));
|
||||
|
||||
// save dllname for debug purposes
|
||||
|
@ -2355,15 +2355,16 @@ dll_user_t *FS_FindLibrary( const char *dllname, qboolean directpath )
|
|||
|
||||
hInst->encrypted = FS_CheckForCrypt( dllpath );
|
||||
|
||||
if( index < 0 && !hInst->encrypted )
|
||||
if( index < 0 && !hInst->encrypted && search )
|
||||
{
|
||||
Q_snprintf( hInst->fullPath, sizeof( hInst->fullPath ), "%s%s", search->filename, dllpath );
|
||||
hInst->custom_loader = false; // we can loading from disk and use normal debugging
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: if search is NULL let the OS found library himself
|
||||
Q_strncpy( hInst->fullPath, dllpath, sizeof( hInst->fullPath ));
|
||||
hInst->custom_loader = true; // loading from pack or wad - for release, debug don't working
|
||||
hInst->custom_loader = (search) ? true : false;
|
||||
}
|
||||
fs_ext_path = false; // always reset direct paths
|
||||
|
||||
|
|
|
@ -226,6 +226,29 @@ void IN_ToggleClientMouse( int newstate, int oldstate )
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_RecalcCenter
|
||||
|
||||
Recalc the center of screen
|
||||
===========
|
||||
*/
|
||||
void IN_RecalcCenter( void )
|
||||
{
|
||||
int width = GetSystemMetrics( SM_CXSCREEN );
|
||||
int height = GetSystemMetrics( SM_CYSCREEN );
|
||||
|
||||
GetWindowRect( host.hWnd, &window_rect );
|
||||
if( window_rect.left < 0 ) window_rect.left = 0;
|
||||
if( window_rect.top < 0 ) window_rect.top = 0;
|
||||
if( window_rect.right >= width ) window_rect.right = width - 1;
|
||||
if( window_rect.bottom >= height - 1 ) window_rect.bottom = height - 1;
|
||||
|
||||
host.window_center_x = (window_rect.right + window_rect.left) / 2;
|
||||
host.window_center_y = (window_rect.top + window_rect.bottom) / 2;
|
||||
SetCursorPos( host.window_center_x, host.window_center_y );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
IN_ActivateMouse
|
||||
|
@ -235,7 +258,6 @@ Called when the window gains focus or changes in some way
|
|||
*/
|
||||
void IN_ActivateMouse( qboolean force )
|
||||
{
|
||||
int width, height;
|
||||
static int oldstate;
|
||||
|
||||
if( !in_mouseinitialized )
|
||||
|
@ -281,18 +303,7 @@ void IN_ActivateMouse( qboolean force )
|
|||
clgame.dllFuncs.IN_ActivateMouse();
|
||||
}
|
||||
|
||||
width = GetSystemMetrics( SM_CXSCREEN );
|
||||
height = GetSystemMetrics( SM_CYSCREEN );
|
||||
|
||||
GetWindowRect( host.hWnd, &window_rect );
|
||||
if( window_rect.left < 0 ) window_rect.left = 0;
|
||||
if( window_rect.top < 0 ) window_rect.top = 0;
|
||||
if( window_rect.right >= width ) window_rect.right = width - 1;
|
||||
if( window_rect.bottom >= height - 1 ) window_rect.bottom = height - 1;
|
||||
|
||||
host.window_center_x = (window_rect.right + window_rect.left) / 2;
|
||||
host.window_center_y = (window_rect.top + window_rect.bottom) / 2;
|
||||
SetCursorPos( host.window_center_x, host.window_center_y );
|
||||
IN_RecalcCenter();
|
||||
|
||||
SetCapture( host.hWnd );
|
||||
ClipCursor( &window_rect );
|
||||
|
@ -498,6 +509,7 @@ LONG IN_WndProc( HWND hWnd, UINT uMsg, UINT wParam, LONG lParam )
|
|||
S_Activate( fActivate, host.hWnd );
|
||||
IN_ActivateMouse( fActivate );
|
||||
Key_ClearStates();
|
||||
IN_RecalcCenter();
|
||||
|
||||
if( host.status == HOST_FRAME )
|
||||
{
|
||||
|
|
|
@ -2188,7 +2188,7 @@ static void Mod_LoadSurfaces( dbspmodel_t *bmod )
|
|||
if(( tex->name[0] == '*' && Q_stricmp( tex->name, "*default" )) || tex->name[0] == '!' )
|
||||
SetBits( out->flags, SURF_DRAWTURB|SURF_DRAWTILED );
|
||||
|
||||
if( !FBitSet( host.features, ENGINE_QUAKE_COMPATIBLE ))
|
||||
if( !CL_IsQuakeCompatible( ))
|
||||
{
|
||||
if( !Q_strncmp( tex->name, "water", 5 ) || !Q_strnicmp( tex->name, "laser", 5 ))
|
||||
SetBits( out->flags, SURF_DRAWTURB|SURF_DRAWTILED );
|
||||
|
|
|
@ -179,6 +179,67 @@ GNU General Public License for more details.
|
|||
#define FRAGMENT_MAX_SIZE 64000 // maximal fragment size
|
||||
#define FRAGMENT_LOCAL_SIZE FRAGMENT_MAX_SIZE // local connection
|
||||
|
||||
// Quake1 Protocol
|
||||
#define PROTOCOL_VERSION_QUAKE 15
|
||||
|
||||
// listed only unmatched ops
|
||||
#define svc_updatestat 3 // [byte] [long] (svc_event)
|
||||
#define svc_version 4 // [long] server version (svc_changing)
|
||||
#define svc_updatename 13 // [byte] [string] (svc_updateuserinfo)
|
||||
#define svc_updatefrags 14 // [byte] [short] (svc_deltatable)
|
||||
#define svc_stopsound 16 // <see code> (svc_resource)
|
||||
#define svc_updatecolors 17 // [byte] [byte] (svc_pings)
|
||||
#define svc_damage 19 // (svc_restoresound)
|
||||
#define svc_spawnbinary 21 // (svc_event_reliable)
|
||||
#define svc_killedmonster 27
|
||||
#define svc_foundsecret 28
|
||||
#define svc_spawnstaticsound 29 // [coord3] [byte] samp [byte] vol [byte] aten
|
||||
#define svc_sellscreen 33 // (svc_restore)
|
||||
// Nehahra added
|
||||
#define svc_showlmp 35 // [string] slotname [string] lmpfilename [coord] x [coord] y
|
||||
#define svc_hidelmp 36 // [string] slotname
|
||||
#define svc_skybox 37 // [string] skyname
|
||||
#define svc_skyboxsize 50 // [coord] size (default is 4096)
|
||||
#define svc_fog 51 // [byte] enable <optional past this point, only included if enable is true>
|
||||
// [float] density [byte] red [byte] green [byte] blue
|
||||
|
||||
// if the high bit of the servercmd is set, the low bits are fast update flags:
|
||||
#define U_MOREBITS (1<<0)
|
||||
#define U_ORIGIN1 (1<<1)
|
||||
#define U_ORIGIN2 (1<<2)
|
||||
#define U_ORIGIN3 (1<<3)
|
||||
#define U_ANGLE2 (1<<4)
|
||||
#define U_NOLERP (1<<5) // don't interpolate movement
|
||||
#define U_FRAME (1<<6)
|
||||
#define U_SIGNAL (1<<7) // just differentiates from other updates
|
||||
|
||||
// svc_update can pass all of the fast update bits, plus more
|
||||
#define U_ANGLE1 (1<<8)
|
||||
#define U_ANGLE3 (1<<9)
|
||||
#define U_MODEL (1<<10)
|
||||
#define U_COLORMAP (1<<11)
|
||||
#define U_SKIN (1<<12)
|
||||
#define U_EFFECTS (1<<13)
|
||||
#define U_LONGENTITY (1<<14)
|
||||
#define U_TRANS (1<<15) // nehahra
|
||||
|
||||
// clientdata flags
|
||||
#define SU_VIEWHEIGHT (1<<0)
|
||||
#define SU_IDEALPITCH (1<<1)
|
||||
#define SU_PUNCH1 (1<<2)
|
||||
#define SU_PUNCH2 (1<<3)
|
||||
#define SU_PUNCH3 (1<<4)
|
||||
#define SU_VELOCITY1 (1<<5)
|
||||
#define SU_VELOCITY2 (1<<6)
|
||||
#define SU_VELOCITY3 (1<<7)
|
||||
//define SU_AIMENT (1<<8) AVAILABLE BIT
|
||||
#define SU_ITEMS (1<<9)
|
||||
#define SU_ONGROUND (1<<10) // no data follows, the bit is it
|
||||
#define SU_INWATER (1<<11) // no data follows, the bit is it
|
||||
#define SU_WEAPONFRAME (1<<12)
|
||||
#define SU_ARMOR (1<<13)
|
||||
#define SU_WEAPON (1<<14)
|
||||
|
||||
extern const char *svc_strings[svc_lastmsg+1];
|
||||
extern const char *clc_strings[clc_lastmsg+1];
|
||||
|
||||
|
|
|
@ -164,6 +164,10 @@ SOURCE=.\client\cl_custom.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_debug.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_demo.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -200,6 +204,10 @@ SOURCE=.\client\cl_pmove.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_qparse.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\client\cl_remap.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
Reference in New Issue