⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cl_main.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
begin
	//Yet another hack to let old demos work
	//the old precache sequence
	if (Cmd_Argc() < 2) then begin
		CM_LoadMap (cl.configstrings[CS_MODELS+1], true, map_checksum);
		CL_RegisterSounds ();
		CL_PrepRefresh ();
		exit;
	end;

	precache_check := CS_MODELS;
	precache_spawncount := StrToInt(Cmd_Argv(1));
	precache_model := nil;
	precache_model_skin := 0;

	CL_RequestNextDownload();
end;


(*
=================
CL_InitLocal
=================
*)
procedure CL_InitLocal;
begin
	cls.state := ca_disconnected;
	cls.realtime := Sys_Milliseconds ();

	CL_InitInput ();

	adr0 := Cvar_Get( 'adr0', '', CVAR_ARCHIVE );
	adr1 := Cvar_Get( 'adr1', '', CVAR_ARCHIVE );
	adr2 := Cvar_Get( 'adr2', '', CVAR_ARCHIVE );
	adr3 := Cvar_Get( 'adr3', '', CVAR_ARCHIVE );
	adr4 := Cvar_Get( 'adr4', '', CVAR_ARCHIVE );
	adr5 := Cvar_Get( 'adr5', '', CVAR_ARCHIVE );
	adr6 := Cvar_Get( 'adr6', '', CVAR_ARCHIVE );
	adr7 := Cvar_Get( 'adr7', '', CVAR_ARCHIVE );
	adr8 := Cvar_Get( 'adr8', '', CVAR_ARCHIVE );

//
// register our variables
//
	cl_stereo_separation := Cvar_Get( 'cl_stereo_separation', '0.4', CVAR_ARCHIVE );
	cl_stereo := Cvar_Get( 'cl_stereo', '0', 0 );

	cl_add_blend := Cvar_Get ('cl_blend', '1', 0);
	cl_add_lights := Cvar_Get ('cl_lights', '1', 0);
	cl_add_particles := Cvar_Get ('cl_particles', '1', 0);
	cl_add_entities := Cvar_Get ('cl_entities', '1', 0);
	cl_gun := Cvar_Get ('cl_gun', '1', 0);
	cl_footsteps := Cvar_Get ('cl_footsteps', '1', 0);
	cl_noskins := Cvar_Get ('cl_noskins', '0', 0);
	cl_autoskins := Cvar_Get ('cl_autoskins', '0', 0);
	cl_predict := Cvar_Get ('cl_predict', '1', 0);
//	cl_minfps := Cvar_Get ('cl_minfps', '5', 0);
	cl_maxfps := Cvar_Get ('cl_maxfps', '90', 0);

	cl_upspeed := Cvar_Get ('cl_upspeed', '200', 0);
	cl_forwardspeed := Cvar_Get ('cl_forwardspeed', '200', 0);
	cl_sidespeed := Cvar_Get ('cl_sidespeed', '200', 0);
	cl_yawspeed := Cvar_Get ('cl_yawspeed', '140', 0);
	cl_pitchspeed := Cvar_Get ('cl_pitchspeed', '150', 0);
	cl_anglespeedkey := Cvar_Get ('cl_anglespeedkey', '1.5', 0);

	cl_run := Cvar_Get ('cl_run', '0', CVAR_ARCHIVE);
	freelook := Cvar_Get( 'freelook', '0', CVAR_ARCHIVE );
	lookspring := Cvar_Get ('lookspring', '0', CVAR_ARCHIVE);
	lookstrafe := Cvar_Get ('lookstrafe', '0', CVAR_ARCHIVE);
	sensitivity := Cvar_Get ('sensitivity', '3', CVAR_ARCHIVE);

	m_pitch := Cvar_Get ('m_pitch', '0.022', CVAR_ARCHIVE);
	m_yaw := Cvar_Get ('m_yaw', '0.022', 0);
	m_forward := Cvar_Get ('m_forward', '1', 0);
	m_side := Cvar_Get ('m_side', '1', 0);

	cl_shownet := Cvar_Get ('cl_shownet', '0', 0);
	cl_showmiss := Cvar_Get ('cl_showmiss', '0', 0);
	cl_showclamp := Cvar_Get ('showclamp', '0', 0);
	cl_timeout := Cvar_Get ('cl_timeout', '120', 0);
	cl_paused := Cvar_Get ('paused', '0', 0);
	cl_timedemo := Cvar_Get ('timedemo', '0', 0);

	rcon_client_password := Cvar_Get ('rcon_password', '', 0);
	rcon_address := Cvar_Get ('rcon_address', '', 0);

	cl_lightlevel := Cvar_Get ('r_lightlevel', '0', 0);

	//
	// userinfo
	//
	info_password := Cvar_Get ('password', '', CVAR_USERINFO);
	info_spectator := Cvar_Get ('spectator', '0', CVAR_USERINFO);
	name := Cvar_Get ('name', 'unnamed', CVAR_USERINFO or CVAR_ARCHIVE);
	skin := Cvar_Get ('skin', 'male/grunt', CVAR_USERINFO or CVAR_ARCHIVE);
	rate := Cvar_Get ('rate', '25000', CVAR_USERINFO or CVAR_ARCHIVE);	// FIXME
	msg := Cvar_Get ('msg', '1', CVAR_USERINFO or CVAR_ARCHIVE);
	hand := Cvar_Get ('hand', '0', CVAR_USERINFO or CVAR_ARCHIVE);
	fov := Cvar_Get ('fov', '90', CVAR_USERINFO or CVAR_ARCHIVE);
	gender := Cvar_Get ('gender', 'male', CVAR_USERINFO or CVAR_ARCHIVE);
	gender_auto := Cvar_Get ('gender_auto', '1', CVAR_ARCHIVE);
	gender.modified := false; // clear this so we know when user sets it manually

	cl_vwep := Cvar_Get ('cl_vwep', '1', CVAR_ARCHIVE);


	//
	// register our commands
	//
	Cmd_AddCommand ('cmd', CL_ForwardToServer_f);
	Cmd_AddCommand ('pause', CL_Pause_f);
	Cmd_AddCommand ('pingservers', CL_PingServers_f);
	Cmd_AddCommand ('skins', CL_Skins_f);

	Cmd_AddCommand ('userinfo', CL_Userinfo_f);
	Cmd_AddCommand ('snd_restart', CL_Snd_Restart_f);

	Cmd_AddCommand ('changing', CL_Changing_f);
	Cmd_AddCommand ('disconnect', CL_Disconnect_f);
	Cmd_AddCommand ('record', CL_Record_f);
	Cmd_AddCommand ('stop', CL_Stop_f);

	Cmd_AddCommand ('quit', CL_Quit_f);

	Cmd_AddCommand ('connect', CL_Connect_f);
	Cmd_AddCommand ('reconnect', CL_Reconnect_f);

	Cmd_AddCommand ('rcon', CL_Rcon_f);

// 	Cmd_AddCommand ('packet', CL_Packet_f); // this is dangerous to leave in

	Cmd_AddCommand ('setenv', CL_Setenv_f );

	Cmd_AddCommand ('precache', CL_Precache_f);

	Cmd_AddCommand ('download', CL_Download_f);

	//
	// forward to server commands
	//
	// the only thing this does is allow command completion
	// to work -- all unknown commands are automatically
	// forwarded to the server
	Cmd_AddCommand ('wave', nil);
	Cmd_AddCommand ('inven', nil);
	Cmd_AddCommand ('kill', nil);
	Cmd_AddCommand ('use', nil);
	Cmd_AddCommand ('drop', nil);
	Cmd_AddCommand ('say', nil);
	Cmd_AddCommand ('say_team', nil);
	Cmd_AddCommand ('info', nil);
	Cmd_AddCommand ('prog', nil);
	Cmd_AddCommand ('give', nil);
	Cmd_AddCommand ('god', nil);
	Cmd_AddCommand ('notarget', nil);
	Cmd_AddCommand ('noclip', nil);
	Cmd_AddCommand ('invuse', nil);
	Cmd_AddCommand ('invprev', nil);
	Cmd_AddCommand ('invnext', nil);
	Cmd_AddCommand ('invdrop', nil);
	Cmd_AddCommand ('weapnext', nil);
	Cmd_AddCommand ('weapprev', nil);
end;



(*
===============
CL_WriteConfiguration

Writes key bindings and archived cvars to config.cfg
===============
*)
procedure CL_WriteConfiguration;
const
  FILEGENTAG = '// generated by quake, do not modify'#10;
var
	f: integer;
	path: array[0..MAX_QPATH-1] of char;
begin
	if (cls.state = ca_uninitialized) then
		exit;

	Com_sprintf (path, sizeof(path),'%s/config.cfg', [FS_Gamedir()]);

  If FileExists(path) then DeleteFile(path);
	f := FileCreate (path);
	if (f = -1) then begin
		Com_Printf ('Couldn''t write config.cfg.'#10);
		exit;
	end;

	FileWrite (f, FILEGENTAG, sizeof(FILEGENTAG));
	Key_WriteBindings (f); 
	FileClose (f);

	Cvar_WriteVariables (path);
end;


(*
==================
CL_FixCvarCheats

==================
*)

type
  cheatvar_p = ^cheatvar_t;
  cheatvar_t = record
	 name: pchar;
	 value: pchar;
	 var_ : cvar_p;
  end;

var
	cheatvars: array[0..11] of cheatvar_t = (
	(name: 'timescale';           value: '1'; var_: nil),
	(name: 'timedemo';            value: '0'; var_: nil),
	(name: 'r_drawworld';         value: '1'; var_: nil),
	(name: 'cl_testlights';       value: '0'; var_: nil),
	(name: 'r_fullbright';        value: '0'; var_: nil),
	(name: 'r_drawflat';          value: '0'; var_: nil),
	(name: 'paused';              value: '0'; var_: nil),
	(name: 'fixedtime';           value: '0'; var_: nil),
	(name: 'sw_draworder';        value: '0'; var_: nil),
	(name: 'gl_lightmap';         value: '0'; var_: nil),
	(name: 'gl_saturatelighting'; value: '0'; var_: nil),
	(name: nil;                   value: nil; var_: nil)
  );

  numcheatvars: integer;


procedure CL_FixCvarCheats;
var
	i: Integer;
	var_: cheatvar_p;
begin
	if (strcmp(cl.configstrings[CS_MAXCLIENTS], '1') = 0) or
		 (cl.configstrings[CS_MAXCLIENTS][0]=#0) then
		exit;		// single player can cheat

	// find all the cvars if we haven't done it yet
	if (numcheatvars = 0) then begin
		while (cheatvars[numcheatvars].name<>nil) do begin
			cheatvars[numcheatvars].var_ := Cvar_Get (cheatvars[numcheatvars].name,
					cheatvars[numcheatvars].value, 0);
			Inc(numcheatvars);
		end;
	end;

	// make sure they are all set to the proper values
  i := 0;
  var_ := @cheatvars;
  while (i < numcheatvars) do begin
		if (strcmp(var_.var_.string_, var_.value))<>0 then begin
			Cvar_Set (var_.name, var_.value);
		end;
    Inc(i);
    Inc(Var_);
	end;
end;

//============================================================================

(*
==================
CL_SendCommand

==================
*)
procedure CL_SendCommand;
begin
	// get new key events
	Sys_SendKeyEvents ();

	// allow mice or other external controllers to add commands
	IN_Commands ();

	// process console commands
	Cbuf_Execute ();

	// fix any cheating cvars
	CL_FixCvarCheats ();

	// send intentions now
	CL_SendCmd ();

	// resend a connection request if necessary
	CL_CheckForResend ();
end;


(*
==================
CL_Frame

==================
*)
var
	extratime: integer;
	lasttimecalled: integer;

procedure CL_Frame (msec: Integer);
var
  now_: integer;
  tmp: string;
begin
	if (dedicated.value<>0) then
		exit;

	extratime := extratime + msec;

	if (cl_timedemo.value = 0) then begin
		if (cls.state = ca_connected) and (extratime < 100) then
			exit;			// don't flood packets out while connecting
		if (extratime < 1000/cl_maxfps.value) then
			exit;			// framerate is too high
	end;

	// let the mouse activate or deactivate
	IN_Frame ();

	// decide the simulation time
	cls.frametime := extratime/1000.0;
	cl.time := cl.time + extratime;
	cls.realtime := curtime;

	extratime := 0;
{$ifdef neverever}
	if (cls.frametime > (1.0 / cl_minfps.value))
		cls.frametime = (1.0 / cl_minfps.value);
{$else}
	if (cls.frametime > (1.0 / 5)) then
		cls.frametime := (1.0 / 5);
{$endif}

	// if in the debugger last frame, don't timeout
	if (msec > 5000) then
		cls.netchan.last_received := Sys_Milliseconds ();

	// fetch results from server
	CL_ReadPackets ();

	// send a new command message to the server
	CL_SendCommand ();

	// predict all unacknowledged movements
	CL_PredictMovement ();        

	// allow rendering DLL change
	VID_CheckChanges ();
	if (not cl.refresh_prepped) and (cls.state = ca_active) then
		CL_PrepRefresh ();

	// update the screen
	if (host_speeds.value<>0) then
		time_before_ref := Sys_Milliseconds ();
	SCR_UpdateScreen ();
	if (host_speeds.value<>0) then
		time_after_ref := Sys_Milliseconds ();

	// update audio
	S_Update (vec3_t(cl.refdef.vieworg), cl.v_forward, cl.v_right, cl.v_up);

	CDAudio_Update(); 

	// advance local effects for next frame
	CL_RunDLights ();
	CL_RunLightStyles ();
	SCR_RunCinematic ();
	SCR_RunConsole ();

	Inc(cls.framecount);

	if ( log_stats.value <>0) then begin        
		if ( cls.state = ca_active ) then begin
			if ( lasttimecalled = 0 ) then begin
				lasttimecalled := Sys_Milliseconds();
				if ( log_stats_file<>0 ) then
					FileWrite( log_stats_file, '0'#10, 2 );
			end
			else
			begin
				now_ := Sys_Milliseconds();

				if ( log_stats_file<>0 ) then begin
          tmp := Format('%d'#10, [now_ - lasttimecalled]);
					FileWrite( log_stats_file, tmp[1], length(tmp));
        end;
				lasttimecalled := now_;
			end;
		end;
	end;
end;


//============================================================================

(*
====================
CL_Init
====================
*)
procedure CL_Init;
begin
	if (dedicated.value<>0) then
		exit;		// nothing running on the client

	// all archived variables will now be loaded

	Con_Init ();
{$IFDEF LINUX}
	S_Init ();
	VID_Init ();
{$ELSE}
	VID_Init ();
	S_Init ();	// sound must be initialized after window is created
{$ENDIF}

	V_Init ();

	net_message.data := @net_message_buffer;
	net_message.maxsize := sizeof(net_message_buffer);

	M_Init ();

	SCR_Init ();
	cls.disable_screen := Integer(true);	// don't draw yet

	CDAudio_Init ();
	CL_InitLocal ();
	IN_Init ();

//	Cbuf_AddText ("exec autoexec.cfg"#10);
	FS_ExecAutoexec ();
	Cbuf_Execute ();

end;


(*
===============
CL_Shutdown

FIXME: this is a callback from Sys_Quit and Com_Error.  It would be better
to run quit through here before the final handoff to the sys code.
===============
*)

var
 isdown: qboolean = false;

procedure CL_Shutdown;
begin
	if (isdown) then begin
		Com_printf ('recursive shutdown'#10);
		exit;
  end;
	isdown := true;

	CL_WriteConfiguration ();

	CDAudio_Shutdown ();
	S_Shutdown();
	IN_Shutdown ();
	VID_Shutdown();
end;


end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -