📄 cl_view.pas
字号:
// register models, pics, and skins
Com_Printf ('Map: %s'#13, [mapname]);
SCR_UpdateScreen;
re.BeginRegistration(mapname);
Com_Printf(' '#13, []);
// precache status bar pics
Com_Printf ('pics'#13, []);
SCR_UpdateScreen;
SCR_TouchPics;
Com_Printf(' '#13, []);
CL_RegisterTEntModels;
num_cl_weaponmodels := 1;
strcpy(cl_weaponmodels[0], 'weapon.md2');
i := 1;
while (i < MAX_MODELS) and (cl.configstrings[CS_MODELS+i][0] <> #0) do
begin
strcpy(name, cl.configstrings[CS_MODELS+i]);
name[37] := #0; // never go beyond one line
if (name[0] <> '*') then
Com_Printf ('%s'#13, [name]);
SCR_UpdateScreen;
Sys_SendKeyEvents; // pump message loop
if (name[0] = '#') then
begin
// special player weapon model
if (num_cl_weaponmodels < MAX_CLIENTWEAPONMODELS) then
begin
strncpy(cl_weaponmodels[num_cl_weaponmodels], cl.configstrings[CS_MODELS+i]+1,
sizeof(cl_weaponmodels[num_cl_weaponmodels]) - 1);
inc(num_cl_weaponmodels);
end;
end
else
begin
cl.model_draw[i] := re.RegisterModel (cl.configstrings[CS_MODELS+i]);
if (name[0] = '*') then
cl.model_clip[i] := CM_InlineModel (cl.configstrings[CS_MODELS+i])
else
cl.model_clip[i] := nil;
end;
if (name[0] <> '*') then
Com_Printf(' '#13, []);
Inc(i);
end;
Com_Printf ('images %i'#13, [i]);
SCR_UpdateScreen;
i := 1;
while (i < MAX_IMAGES) and (cl.configstrings[CS_IMAGES+i][0]<>#0) do
begin
cl.image_precache[i] := re.RegisterPic (cl.configstrings[CS_IMAGES+i]);
Sys_SendKeyEvents; // pump message loop
inc(i);
end;
Com_Printf(' '#13, []);
i := 0;
while i < MAX_CLIENTS do
begin
if (cl.configstrings[CS_PLAYERSKINS+i][0] = #0) then
begin
Inc(i);
Continue;
end;
Com_Printf ('client %i'#13, [i]);
SCR_UpdateScreen;
Sys_SendKeyEvents; // pump message loop
CL_ParseClientinfo(i);
Com_Printf(' '#13, []);
Inc(i);
end;
CL_LoadClientinfo (@cl.baseclientinfo, 'unnamed\male/grunt');
// set sky textures and speed
Com_Printf ('sky %d'#13, [i]);
SCR_UpdateScreen;
rotate := atof(cl.configstrings[CS_SKYROTATE]);
sscanf(cl.configstrings[CS_SKYAXIS], '%f %f %f', [@axis[0], @axis[1], @axis[2]]);
re.SetSky (cl.configstrings[CS_SKY], rotate, axis);
Com_Printf (' '#13, []);
// the renderer can now free unneeded stuff
re.EndRegistration;
// clear any lines of console text
Con_ClearNotify;
SCR_UpdateScreen ();
cl.refresh_prepped := true;
cl.force_refdef := true; // make sure we have a valid refdef
// start the cd track
CDAudio_Play (StrToInt(cl.configstrings[CS_CDTRACK]), true);
end;
{
====================
CalcFov
====================
}
function CalcFov(fov_x, width, height: Single): Single;
var
a, x: Single;
begin
if (fov_x < 1) or (fov_x > 179) then
Com_Error (ERR_DROP, 'Bad fov: %f', [fov_x]);
x := width / tan(fov_x/360*M_PI);
a := arctan (height/x);
a := a*360/M_PI;
result := a;
end;
//============================================================================
// gun frame debugging functions
procedure V_Gun_Next_f; cdecl;
begin
inc(gun_frame);
Com_Printf ('frame %d'#10, [gun_frame]);
end;
procedure V_Gun_Prev_f; cdecl;
begin
dec(gun_frame);
if (gun_frame < 0) then gun_frame := 0;
Com_Printf ('frame %d'#10, [gun_frame]);
end;
procedure V_Gun_Model_f; cdecl;
var
name: array[0..MAX_QPATH-1] of char;
begin
if (Cmd_Argc <> 2) then
begin
gun_model := nil;
exit;
end;
Com_sprintf (name, sizeof(name), 'models/%s/tris.md2', [Cmd_Argv(1)]);
gun_model := re.RegisterModel (name);
end;
//============================================================================
{
=================
SCR_DrawCrosshair
=================
}
procedure SCR_DrawCrosshair;
begin
if not (crosshair.value <> 0) then exit;
if crosshair.modified then
begin
crosshair.modified := false;
SCR_TouchPics;
end;
if (crosshair_pic[0] = #0) then exit; //TER: same as above , first check value (0 = false, !0 = true)
re.DrawPic (scr_vrect.x + ((scr_vrect.width - crosshair_width) shr 1),
scr_vrect.y + ((scr_vrect.height - crosshair_height) shr 1), crosshair_pic);
end;
{
==================
V_RenderView
==================
}
procedure V_RenderView( stereo_separation: single );
var
tmp: vec3_t;
begin
//extern int entitycmpfnc( const entity_t *, const entity_t * );
if (cls.state <> ca_active) then
exit;
if (not cl.refresh_prepped) then
exit; // still loading
if (cl_timedemo.value <> 0) then begin
if (not cl.timedemo_start <> 0) then
cl.timedemo_start := Sys_Milliseconds ();
Inc(cl.timedemo_frames);
end;
// an invalid frame will just use the exact previous refdef
// we can't use the old frame if the video mode has changed, though...
if ( cl.frame.valid and (cl.force_refdef or (cl_paused.value = 0))) then begin
cl.force_refdef := false;
V_ClearScene ();
// build a refresh entity list and calc cl.sim*
// this also calls CL_CalcViewValues which loads
// v_forward, etc.
CL_AddEntities ();
if (cl_testparticles.value<>0) then
V_TestParticles ();
if (cl_testentities.value<>0) then
V_TestEntities ();
if (cl_testlights.value<>0) then
V_TestLights ();
if (cl_testblend.value<>0) then begin
cl.refdef.blend[0] := 1;
cl.refdef.blend[1] := 0.5;
cl.refdef.blend[2] := 0.25;
cl.refdef.blend[3] := 0.5;
end;
// offset vieworg appropriately if we're doing stereo separation
if ( stereo_separation <> 0 ) then begin
VectorScale( cl.v_right, stereo_separation, tmp );
VectorAdd( vec3_t(cl.refdef.vieworg), tmp, vec3_t(cl.refdef.vieworg) );
end;
// never let it sit exactly on a node line, because a water plane can
// dissapear when viewed with the eye exactly on it.
// the server protocol only specifies to 1/8 pixel, so add 1/16 in each axis
cl.refdef.vieworg[0] := cl.refdef.vieworg[0] + 1.0/16;
cl.refdef.vieworg[1] := cl.refdef.vieworg[1] + 1.0/16;
cl.refdef.vieworg[2] := cl.refdef.vieworg[2] + 1.0/16;
cl.refdef.x := scr_vrect.x;
cl.refdef.y := scr_vrect.y;
cl.refdef.width := scr_vrect.width;
cl.refdef.height := scr_vrect.height;
cl.refdef.fov_y := CalcFov (cl.refdef.fov_x, cl.refdef.width, cl.refdef.height);
cl.refdef.time := cl.time*0.001;
cl.refdef.areabits := @cl.frame.areabits[0];
if (cl_add_entities.value = 0) then
r_numentities := 0;
if (cl_add_particles.value = 0) then
r_numparticles := 0;
if (cl_add_lights.value = 0) then
r_numdlights := 0;
if (cl_add_blend.value = 0) then begin
VectorClear (vec3_p(@cl.refdef.blend)^);
end;
cl.refdef.num_entities := r_numentities;
cl.refdef.entities := @r_entities;
cl.refdef.num_particles := r_numparticles;
cl.refdef.particles := @r_particles;
cl.refdef.num_dlights := r_numdlights;
cl.refdef.dlights := @r_dlights;
cl.refdef.lightstyles := @r_lightstyles;
cl.refdef.rdflags := cl.frame.playerstate.rdflags;
// sort entities for better cache locality
{$IFDEF TODO}
qsort( cl.refdef.entities, cl.refdef.num_entities, sizeof( cl.refdef.entities[0] ), (int (*)(const void *, const void *))entitycmpfnc );
{$ENDIF}
end;
re.RenderFrame (@cl.refdef);
if (cl_stats.value <> 0) then
Com_Printf ('ent:%d lt:%d part:%d'#10, [r_numentities, r_numdlights, r_numparticles]);
if ( log_stats.value<>0) and ( log_stats_file <> 0 ) then
Write( log_stats_file,
format('%d,%d,%d,', [r_numentities, r_numdlights, r_numparticles]));
SCR_AddDirtyPoint (scr_vrect.x, scr_vrect.y);
SCR_AddDirtyPoint (scr_vrect.x+scr_vrect.width-1,
scr_vrect.y+scr_vrect.height-1);
SCR_DrawCrosshair ();
end;
{
=============
V_Viewpos_f
=============
}
procedure V_Viewpos_f; cdecl;
begin
Com_Printf ('(%d %d %d) : %d'#10, [cl.refdef.vieworg[0],
cl.refdef.vieworg[1], cl.refdef.vieworg[2],
cl.refdef.viewangles[YAW]]);
end;
{
=============
V_Init
=============
}
procedure V_Init;
begin
Cmd_AddCommand ('gun_next', V_Gun_Next_f);
Cmd_AddCommand ('gun_prev', V_Gun_Prev_f);
Cmd_AddCommand ('gun_model', V_Gun_Model_f);
Cmd_AddCommand ('viewpos', V_Viewpos_f);
crosshair := Cvar_Get ('crosshair', '0', CVAR_ARCHIVE);
cl_testblend := Cvar_Get ('cl_testblend', '0', 0);
cl_testparticles := Cvar_Get ('cl_testparticles', '0', 0);
cl_testentities := Cvar_Get ('cl_testentities', '0', 0);
cl_testlights := Cvar_Get ('cl_testlights', '0', 0);
cl_stats := Cvar_Get ('cl_stats', '0', 0);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -