📄 cl_main.c
字号:
} else if ( print_level == PRINT_WARNING ) {
Com_Printf (S_COLOR_YELLOW "%s", msg); // yellow
} else if ( print_level == PRINT_DEVELOPER ) {
Com_DPrintf (S_COLOR_RED "%s", msg); // red
}
}
/*
============
CL_ShutdownRef
============
*/
void CL_ShutdownRef( void ) {
if ( !re.Shutdown ) {
return;
}
re.Shutdown( qtrue );
Com_Memset( &re, 0, sizeof( re ) );
}
/*
============
CL_InitRenderer
============
*/
void CL_InitRenderer( void ) {
// this sets up the renderer and calls R_Init
re.BeginRegistration( &cls.glconfig );
// load character sets
cls.charSetShader = re.RegisterShader( "gfx/2d/bigchars" );
cls.whiteShader = re.RegisterShader( "white" );
cls.consoleShader = re.RegisterShader( "console" );
g_console_field_width = cls.glconfig.vidWidth / SMALLCHAR_WIDTH - 2;
g_consoleField.widthInChars = g_console_field_width;
}
/*
============================
CL_StartHunkUsers
After the server has cleared the hunk, these will need to be restarted
This is the only place that any of these functions are called from
============================
*/
void CL_StartHunkUsers( void ) {
if (!com_cl_running) {
return;
}
if ( !com_cl_running->integer ) {
return;
}
if ( !cls.rendererStarted ) {
cls.rendererStarted = qtrue;
CL_InitRenderer();
}
if ( !cls.soundStarted ) {
cls.soundStarted = qtrue;
S_Init();
}
if ( !cls.soundRegistered ) {
cls.soundRegistered = qtrue;
S_BeginRegistration();
}
if ( !cls.uiStarted ) {
cls.uiStarted = qtrue;
CL_InitUI();
}
}
/*
============
CL_RefMalloc
============
*/
void *CL_RefMalloc( int size ) {
return Z_TagMalloc( size, TAG_RENDERER );
}
int CL_ScaledMilliseconds(void) {
return Sys_Milliseconds()*com_timescale->value;
}
/*
============
CL_InitRef
============
*/
void CL_InitRef( void ) {
refimport_t ri;
refexport_t *ret;
Com_Printf( "----- Initializing Renderer ----\n" );
ri.Cmd_AddCommand = Cmd_AddCommand;
ri.Cmd_RemoveCommand = Cmd_RemoveCommand;
ri.Cmd_Argc = Cmd_Argc;
ri.Cmd_Argv = Cmd_Argv;
ri.Cmd_ExecuteText = Cbuf_ExecuteText;
ri.Printf = CL_RefPrintf;
ri.Error = Com_Error;
ri.Milliseconds = CL_ScaledMilliseconds;
ri.Malloc = CL_RefMalloc;
ri.Free = Z_Free;
#ifdef HUNK_DEBUG
ri.Hunk_AllocDebug = Hunk_AllocDebug;
#else
ri.Hunk_Alloc = Hunk_Alloc;
#endif
ri.Hunk_AllocateTempMemory = Hunk_AllocateTempMemory;
ri.Hunk_FreeTempMemory = Hunk_FreeTempMemory;
ri.CM_DrawDebugSurface = CM_DrawDebugSurface;
ri.FS_ReadFile = FS_ReadFile;
ri.FS_FreeFile = FS_FreeFile;
ri.FS_WriteFile = FS_WriteFile;
ri.FS_FreeFileList = FS_FreeFileList;
ri.FS_ListFiles = FS_ListFiles;
ri.FS_FileIsInPAK = FS_FileIsInPAK;
ri.FS_FileExists = FS_FileExists;
ri.Cvar_Get = Cvar_Get;
ri.Cvar_Set = Cvar_Set;
// cinematic stuff
ri.CIN_UploadCinematic = CIN_UploadCinematic;
ri.CIN_PlayCinematic = CIN_PlayCinematic;
ri.CIN_RunCinematic = CIN_RunCinematic;
ret = GetRefAPI( REF_API_VERSION, &ri );
#if defined __USEA3D && defined __A3D_GEOM
hA3Dg_ExportRenderGeom (ret);
#endif
Com_Printf( "-------------------------------\n");
if ( !ret ) {
Com_Error (ERR_FATAL, "Couldn't initialize refresh" );
}
re = *ret;
// unpause so the cgame definately gets a snapshot and renders a frame
Cvar_Set( "cl_paused", "0" );
}
//===========================================================================================
void CL_SetModel_f( void ) {
char *arg;
char name[256];
arg = Cmd_Argv( 1 );
if (arg[0]) {
Cvar_Set( "model", arg );
Cvar_Set( "headmodel", arg );
} else {
Cvar_VariableStringBuffer( "model", name, sizeof(name) );
Com_Printf("model is set to %s\n", name);
}
}
/*
====================
CL_Init
====================
*/
void CL_Init( void ) {
Com_Printf( "----- Client Initialization -----\n" );
Con_Init ();
CL_ClearState ();
cls.state = CA_DISCONNECTED; // no longer CA_UNINITIALIZED
cls.realtime = 0;
CL_InitInput ();
//
// register our variables
//
cl_noprint = Cvar_Get( "cl_noprint", "0", 0 );
cl_motd = Cvar_Get ("cl_motd", "1", 0);
cl_timeout = Cvar_Get ("cl_timeout", "200", 0);
cl_timeNudge = Cvar_Get ("cl_timeNudge", "0", CVAR_TEMP );
cl_shownet = Cvar_Get ("cl_shownet", "0", CVAR_TEMP );
cl_showSend = Cvar_Get ("cl_showSend", "0", CVAR_TEMP );
cl_showTimeDelta = Cvar_Get ("cl_showTimeDelta", "0", CVAR_TEMP );
cl_freezeDemo = Cvar_Get ("cl_freezeDemo", "0", CVAR_TEMP );
rcon_client_password = Cvar_Get ("rconPassword", "", CVAR_TEMP );
cl_activeAction = Cvar_Get( "activeAction", "", CVAR_TEMP );
cl_timedemo = Cvar_Get ("timedemo", "0", 0);
cl_avidemo = Cvar_Get ("cl_avidemo", "0", 0);
cl_forceavidemo = Cvar_Get ("cl_forceavidemo", "0", 0);
rconAddress = Cvar_Get ("rconAddress", "", 0);
cl_yawspeed = Cvar_Get ("cl_yawspeed", "140", CVAR_ARCHIVE);
cl_pitchspeed = Cvar_Get ("cl_pitchspeed", "140", CVAR_ARCHIVE);
cl_anglespeedkey = Cvar_Get ("cl_anglespeedkey", "1.5", 0);
cl_maxpackets = Cvar_Get ("cl_maxpackets", "30", CVAR_ARCHIVE );
cl_packetdup = Cvar_Get ("cl_packetdup", "1", CVAR_ARCHIVE );
cl_run = Cvar_Get ("cl_run", "1", CVAR_ARCHIVE);
cl_sensitivity = Cvar_Get ("sensitivity", "5", CVAR_ARCHIVE);
cl_mouseAccel = Cvar_Get ("cl_mouseAccel", "0", CVAR_ARCHIVE);
cl_freelook = Cvar_Get( "cl_freelook", "1", CVAR_ARCHIVE );
cl_showMouseRate = Cvar_Get ("cl_showmouserate", "0", 0);
cl_allowDownload = Cvar_Get ("cl_allowDownload", "0", CVAR_ARCHIVE);
cl_conXOffset = Cvar_Get ("cl_conXOffset", "0", 0);
#ifdef MACOS_X
// In game video is REALLY slow in Mac OS X right now due to driver slowness
cl_inGameVideo = Cvar_Get ("r_inGameVideo", "0", CVAR_ARCHIVE);
#else
cl_inGameVideo = Cvar_Get ("r_inGameVideo", "1", CVAR_ARCHIVE);
#endif
cl_serverStatusResendTime = Cvar_Get ("cl_serverStatusResendTime", "750", 0);
// init autoswitch so the ui will have it correctly even
// if the cgame hasn't been started
Cvar_Get ("cg_autoswitch", "1", CVAR_ARCHIVE);
m_pitch = Cvar_Get ("m_pitch", "0.022", CVAR_ARCHIVE);
m_yaw = Cvar_Get ("m_yaw", "0.022", CVAR_ARCHIVE);
m_forward = Cvar_Get ("m_forward", "0.25", CVAR_ARCHIVE);
m_side = Cvar_Get ("m_side", "0.25", CVAR_ARCHIVE);
#ifdef MACOS_X
// Input is jittery on OS X w/o this
m_filter = Cvar_Get ("m_filter", "1", CVAR_ARCHIVE);
#else
m_filter = Cvar_Get ("m_filter", "0", CVAR_ARCHIVE);
#endif
cl_motdString = Cvar_Get( "cl_motdString", "", CVAR_ROM );
Cvar_Get( "cl_maxPing", "800", CVAR_ARCHIVE );
// userinfo
Cvar_Get ("name", "UnnamedPlayer", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("rate", "3000", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("snaps", "20", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("model", "sarge", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("headmodel", "sarge", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("team_model", "james", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("team_headmodel", "*james", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("g_redTeam", "Stroggs", CVAR_SERVERINFO | CVAR_ARCHIVE);
Cvar_Get ("g_blueTeam", "Pagans", CVAR_SERVERINFO | CVAR_ARCHIVE);
Cvar_Get ("color1", "4", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("color2", "5", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("handicap", "100", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("teamtask", "0", CVAR_USERINFO );
Cvar_Get ("sex", "male", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("cl_anonymous", "0", CVAR_USERINFO | CVAR_ARCHIVE );
Cvar_Get ("password", "", CVAR_USERINFO);
Cvar_Get ("cg_predictItems", "1", CVAR_USERINFO | CVAR_ARCHIVE );
// cgame might not be initialized before menu is used
Cvar_Get ("cg_viewsize", "100", CVAR_ARCHIVE );
//
// register our commands
//
Cmd_AddCommand ("cmd", CL_ForwardToServer_f);
Cmd_AddCommand ("configstrings", CL_Configstrings_f);
Cmd_AddCommand ("clientinfo", CL_Clientinfo_f);
Cmd_AddCommand ("snd_restart", CL_Snd_Restart_f);
Cmd_AddCommand ("vid_restart", CL_Vid_Restart_f);
Cmd_AddCommand ("disconnect", CL_Disconnect_f);
Cmd_AddCommand ("record", CL_Record_f);
Cmd_AddCommand ("demo", CL_PlayDemo_f);
Cmd_AddCommand ("cinematic", CL_PlayCinematic_f);
Cmd_AddCommand ("stoprecord", CL_StopRecord_f);
Cmd_AddCommand ("connect", CL_Connect_f);
Cmd_AddCommand ("reconnect", CL_Reconnect_f);
Cmd_AddCommand ("localservers", CL_LocalServers_f);
Cmd_AddCommand ("globalservers", CL_GlobalServers_f);
Cmd_AddCommand ("rcon", CL_Rcon_f);
Cmd_AddCommand ("setenv", CL_Setenv_f );
Cmd_AddCommand ("ping", CL_Ping_f );
Cmd_AddCommand ("serverstatus", CL_ServerStatus_f );
Cmd_AddCommand ("showip", CL_ShowIP_f );
Cmd_AddCommand ("fs_openedList", CL_OpenedPK3List_f );
Cmd_AddCommand ("fs_referencedList", CL_ReferencedPK3List_f );
Cmd_AddCommand ("model", CL_SetModel_f );
CL_InitRef();
SCR_Init ();
Cbuf_Execute ();
Cvar_Set( "cl_running", "1" );
Com_Printf( "----- Client Initialization Complete -----\n" );
}
/*
===============
CL_Shutdown
===============
*/
void CL_Shutdown( void ) {
static qboolean recursive = qfalse;
Com_Printf( "----- CL_Shutdown -----\n" );
if ( recursive ) {
printf ("recursive shutdown\n");
return;
}
recursive = qtrue;
CL_Disconnect( qtrue );
S_Shutdown();
CL_ShutdownRef();
CL_ShutdownUI();
Cmd_RemoveCommand ("cmd");
Cmd_RemoveCommand ("configstrings");
Cmd_RemoveCommand ("userinfo");
Cmd_RemoveCommand ("snd_restart");
Cmd_RemoveCommand ("vid_restart");
Cmd_RemoveCommand ("disconnect");
Cmd_RemoveCommand ("record");
Cmd_RemoveCommand ("demo");
Cmd_RemoveCommand ("cinematic");
Cmd_RemoveCommand ("stoprecord");
Cmd_RemoveCommand ("connect");
Cmd_RemoveCommand ("localservers");
Cmd_RemoveCommand ("globalservers");
Cmd_RemoveCommand ("rcon");
Cmd_RemoveCommand ("setenv");
Cmd_RemoveCommand ("ping");
Cmd_RemoveCommand ("serverstatus");
Cmd_RemoveCommand ("showip");
Cmd_RemoveCommand ("model");
Cvar_Set( "cl_running", "0" );
recursive = qfalse;
Com_Memset( &cls, 0, sizeof( cls ) );
Com_Printf( "-----------------------\n" );
}
static void CL_SetServerInfo(serverInfo_t *server, const char *info, int ping) {
if (server) {
if (info) {
server->clients = atoi(Info_ValueForKey(info, "clients"));
Q_strncpyz(server->hostName,Info_ValueForKey(info, "hostname"), MAX_NAME_LENGTH);
Q_strncpyz(server->mapName, Info_ValueForKey(info, "mapname"), MAX_NAME_LENGTH);
server->maxClients = atoi(Info_ValueForKey(info, "sv_maxclients"));
Q_strncpyz(server->game,Info_ValueForKey(info, "game"), MAX_NAME_LENGTH);
server->gameType = atoi(Info_ValueForKey(info, "gametype"));
server->netType = atoi(Info_ValueForKey(info, "nettype"));
server->minPing = atoi(Info_ValueForKey(info, "minping"));
server->maxPing = atoi(Info_ValueForKey(info, "maxping"));
server->punkbuster = atoi(Info_ValueForKey(info, "punkbuster"));
}
server->ping = ping;
}
}
static void CL_SetServerInfoByAddress(netadr_t from, const char *info, int ping) {
int i;
for (i = 0; i < MAX_OTHER_SERVERS; i++) {
if (NET_CompareAdr(from, cls.localServers[i].adr)) {
CL_SetServerInfo(&cls.localServers[i], info, ping);
}
}
for (i = 0; i < MAX_OTHER_SERVERS; i++) {
if (NET_CompareAdr(from, cls.mplayerServers[i].adr)) {
CL_SetServerInfo(&cls.mplayerServers[i], info, ping);
}
}
for (i = 0; i < MAX_GLOBAL_SERVERS; i++) {
if (NET_CompareAdr(from, cls.globalServers[i].adr)) {
CL_SetServerInfo(&cls.globalServers[i], info, ping);
}
}
for (i = 0; i < MAX_OTHER_SERVERS; i++) {
if (NET_CompareAdr(from, cls.favoriteServers[i].adr)) {
CL_SetServerInfo(&cls.favoriteServers[i], info, ping);
}
}
}
/*
===================
CL_ServerInfoPacket
===================
*/
void CL_ServerInfoPacket( netadr_t from, msg_t *msg ) {
int i, type;
char info[MAX_INFO_STRING];
char* str;
char *infoString;
int prot;
infoString = MSG_ReadString( msg );
// if this isn't the correct protocol version, ignore it
prot = atoi( Info_ValueForKey( infoString, "protocol" ) );
if ( prot != PROTOCOL_VERSION ) {
Com_DPrintf( "Different protocol info packet: %s\n", infoString );
return;
}
// iterate servers waiting for ping response
for (i=0; i<MAX_PINGREQUESTS; i++)
{
if ( cl_pinglist[i].adr.port && !cl_pinglist[i].time && NET_CompareAdr( from, cl_pinglist[i].adr ) )
{
// calc ping time
cl_pinglist[i].time = cls.realtime - cl_pinglist[i].start + 1;
Com_DPrintf( "ping time %dms from %s\n", cl_pinglist[i].time, NET_AdrToString( from ) );
// save of info
Q_strncpyz( cl_pinglist[i].info, infoString, sizeof( cl_pinglist[i].info ) );
// tack on the net type
// NOTE: make sure these types are in sync with the netnames strings in the UI
switch (from.type)
{
case NA_BROADCAST:
case NA_IP:
str = "udp";
type = 1;
break;
case NA_IPX:
case NA_BROADCAST_IPX:
str = "ipx";
type = 2;
break;
default:
str = "???";
type = 0;
break;
}
Info_SetValueForKey( cl_pinglist[i].info, "nettype", va("%d", type) );
CL_SetServerInfoByAddress(from, infoString, cl_pinglist[i].time);
return;
}
}
// if not just sent a local broadcast or pinging local servers
if (cls.pingUpdateSource != AS_LOCAL) {
return;
}
for ( i = 0 ; i < MAX_OTHER_SERVERS ; i++ ) {
// empty slot
if ( cls.localServers[i].adr.port == 0 ) {
break;
}
// avoid duplicate
if ( NET_CompareAdr( from, cls.localServers[i].adr ) ) {
return;
}
}
if ( i == MAX_OTHER_SERVERS ) {
Com_DPrintf( "MAX_OTHER_SERVERS hit, dropping infoResponse\n" );
return;
}
// add this to the list
cls.numlocalservers = i+1;
cls.localServers[i].adr = from;
cls.localServers[i].clients = 0;
cls.localServers[i].hostName[0] = '\0';
cls.localServers[i].mapName[0] = '\0';
cls.localServers[i].maxClients = 0;
cls.localServers[i].maxPing = 0;
cls.localServers[i].minPing = 0;
cls.localServers[i].ping = -1;
cls.localServers[i].game[0] = '\0';
cls.localServers[i].gameType = 0;
cls.localServers[i].netType = from.type;
cls.localServers[i].punkbuster = 0;
Q_strncpyz( info, MSG_ReadString( msg ), MAX_INFO_STRING );
if (strlen(info
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -