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

📄 r_misc.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
Called every time the vid structure or r_refdef changes.
Guaranteed to be called before the first refresh
===============
*)

procedure R_ViewChanged(vr: vrect_p);
var
  i: Integer;
begin
  r_refdef.vrect := vr^;

  r_refdef.horizontalFieldOfView := 2 * tan(r_newrefdef.fov_x / 360 * M_PI);
  verticalFieldOfView := 2 * tan(r_newrefdef.fov_y / 360 * M_PI);

  r_refdef.fvrectx := r_refdef.vrect.x;
  r_refdef.fvrectx_adj := r_refdef.vrect.x - 0.5;
  r_refdef.vrect_x_adj_shift20 := (r_refdef.vrect.x shl 20) + (1 shl 19) - 1;
  r_refdef.fvrecty := r_refdef.vrect.y;
  r_refdef.fvrecty_adj := r_refdef.vrect.y - 0.5;
  r_refdef.vrectright := r_refdef.vrect.x + r_refdef.vrect.width;
  r_refdef.vrectright_adj_shift20 := (r_refdef.vrectright shl 20) + (1 shl 19) - 1;
  r_refdef.fvrectright := r_refdef.vrectright;
  r_refdef.fvrectright_adj := r_refdef.vrectright - 0.5;
  r_refdef.vrectrightedge := r_refdef.vrectright - 0.99;
  r_refdef.vrectbottom := r_refdef.vrect.y + r_refdef.vrect.height;
  r_refdef.fvrectbottom := r_refdef.vrectbottom;
  r_refdef.fvrectbottom_adj := r_refdef.vrectbottom - 0.5;

  r_refdef.aliasvrect.x := Trunc(r_refdef.vrect.x * r_aliasuvscale);
  r_refdef.aliasvrect.y := Trunc(r_refdef.vrect.y * r_aliasuvscale);
  r_refdef.aliasvrect.width := Trunc(r_refdef.vrect.width * r_aliasuvscale);
  r_refdef.aliasvrect.height := Trunc(r_refdef.vrect.height * r_aliasuvscale);
  r_refdef.aliasvrectright := r_refdef.aliasvrect.x + r_refdef.aliasvrect.width;
  r_refdef.aliasvrectbottom := r_refdef.aliasvrect.y + r_refdef.aliasvrect.height;

  xOrigin := r_refdef.xOrigin;
  yOrigin := r_refdef.yOrigin;

// values for perspective projection
// if math were exact, the values would range from 0.5 to to range+0.5
// hopefully they wll be in the 0.000001 to range+.999999 and truncate
// the polygon rasterization will never render in the first row or column
// but will definately render in the [range] row and column, so adjust the
// buffer origin to get an exact edge to edge fill
  xcenter := (r_refdef.vrect.width * XCENTERING) + r_refdef.vrect.x - 0.5;
  aliasxcenter := xcenter * r_aliasuvscale;
  ycenter := (r_refdef.vrect.height * YCENTERING) + r_refdef.vrect.y - 0.5;
  aliasycenter := ycenter * r_aliasuvscale;

  xscale := r_refdef.vrect.width / r_refdef.horizontalFieldOfView;
  aliasxscale := xscale * r_aliasuvscale;
  xscaleinv := 1.0 / xscale;

  yscale := xscale;
  aliasyscale := yscale * r_aliasuvscale;
  yscaleinv := 1.0 / yscale;
  xscaleshrink := (r_refdef.vrect.width - 6) / r_refdef.horizontalFieldOfView;
  yscaleshrink := xscaleshrink;

// left side clip
  screenedge[0].normal[0] := -1.0 / (xOrigin * r_refdef.horizontalFieldOfView);
  screenedge[0].normal[1] := 0;
  screenedge[0].normal[2] := 1;
  screenedge[0]._type := PLANE_ANYZ;

// right side clip
  screenedge[1].normal[0] := 1.0 / ((1.0 - xOrigin) * r_refdef.horizontalFieldOfView);
  screenedge[1].normal[1] := 0;
  screenedge[1].normal[2] := 1;
  screenedge[1]._type := PLANE_ANYZ;

// top side clip
  screenedge[2].normal[0] := 0;
  screenedge[2].normal[1] := -1.0 / (yOrigin * verticalFieldOfView);
  screenedge[2].normal[2] := 1;
  screenedge[2]._type := PLANE_ANYZ;

// bottom side clip
  screenedge[3].normal[0] := 0;
  screenedge[3].normal[1] := 1.0 / ((1.0 - yOrigin) * verticalFieldOfView);
  screenedge[3].normal[2] := 1;
  screenedge[3]._type := PLANE_ANYZ;

  for i := 0 to 3 do
    VectorNormalize(screenedge[i].normal);

  D_ViewChanged;
end;

(*
===============
R_SetupFrame
===============
*)

procedure R_SetupFrame;
var
  i: Integer;
  vrect: vrect_t;
begin
  if (r_fullbright^.modified) then
  begin
    r_fullbright^.modified := false;
    D_FlushCaches; // so all lighting changes
  end;

  Inc(r_framecount);

// build the transformation matrix for the given view angles
  VectorCopy(r_refdef.vieworg, modelorg);
  VectorCopy(r_refdef.vieworg, r_origin);

  AngleVectors(r_refdef.viewangles, @vpn, @vright, @vup);

// current viewleaf
  if ((r_newrefdef.rdflags and RDF_NOWORLDMODEL) = 0) then
  begin
    r_viewleaf := Mod_PointInLeaf(r_origin, r_worldmodel);
    r_viewcluster := r_viewleaf^.cluster;
  end;

  if ((sw_waterwarp^.value <> 0) and ((r_newrefdef.rdflags and RDF_UNDERWATER) <> 0)) then
    r_dowarp := true
  else
    r_dowarp := false;

  if (r_dowarp) then
  begin // warp into off screen buffer
    vrect.x := 0;
    vrect.y := 0;

    if r_newrefdef.width < WARP_WIDTH then
      vrect.width := r_newrefdef.width
    else
      vrect.width := WARP_WIDTH;

    if r_newrefdef.height < WARP_HEIGHT then
      vrect.height := r_newrefdef.height
    else
      vrect.height := WARP_HEIGHT;

    d_viewbuffer := @r_warpbuffer;
    r_screenwidth := WARP_WIDTH;
  end
  else
  begin
    vrect.x := r_newrefdef.x;
    vrect.y := r_newrefdef.y;
    vrect.width := r_newrefdef.width;
    vrect.height := r_newrefdef.height;

    d_viewbuffer := vid.buffer;
    r_screenwidth := vid.rowbytes;
  end;

  R_ViewChanged(@vrect);

// start off with just the four screen edge clip planes
  R_TransformFrustum;
  R_SetUpFrustumIndexes;

// save base values
  VectorCopy(vpn, base_vpn);
  VectorCopy(vright, base_vright);
  VectorCopy(vup, base_vup);

// clear frame counts
  c_faceclip := 0;
  d_spanpixcount := 0;
  r_polycount := 0;
  r_drawnpolycount := 0;
  r_wholepolycount := 0;
  r_amodels_drawn := 0;
  r_outofsurfaces := 0;
  r_outofedges := 0;

// d_setup
  d_roverwrapped := false;
  d_initial_rover := sc_rover;

  d_minmip := Trunc(sw_mipcap^.value);
  if (d_minmip > 3) then
    d_minmip := 3
  else
    if (d_minmip < 0) then
      d_minmip := 0;

  for I := 0 to NUM_MIPS - 2 do
    d_scalemip[i] := basemip[i] * sw_mipscale^.value;

  d_aflatcolor := 0;
end;

{$IFNDEF id386}
(*
================
R_SurfacePatch
================
*)

procedure R_SurfacePatch;
begin
 // we only patch code on Intel
end;
{$ENDIF}

(*
==============================================================================

      SCREEN SHOTS

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

(*
==============
WritePCXfile
==============
*)

procedure WritePCXfile(filename: PChar; data: PByte; width, height,
  rowbytes: Integer; palette: PByte);
var
  i, j, length: Integer;
  pcx: pcx_p;
  pack: PByte;
  f: Integer; // was File;
begin
  //pcx := AllocMem(width*height*2+1000);
  pcx := pcx_p(malloc(width * height * 2 + 1000)); // changed by fab
  if (pcx = nil) then
    Exit;

  pcx^.manufacturer := #$0A; // PCX id
  pcx^.version := #5; // 256 color
  pcx^.encoding := #1; // uncompressed
  pcx^.bits_per_pixel := #8; // 256 color
  pcx^.xmin := 0;
  pcx^.ymin := 0;
  pcx^.xmax := LittleShort(width - 1);
  pcx^.ymax := LittleShort(height - 1);
  pcx^.hres := LittleShort(width);
  pcx^.vres := LittleShort(height);
  //FillChar(pcx^.palette,SizeOf(pcx^.palette),0);
  memset(@pcx^.palette, 0, SizeOf(pcx^.palette)); //changed by fab
  pcx^.color_planes := 1; // chunky image
  pcx^.bytes_per_line := LittleShort(width);
  pcx^.palette_type := LittleShort(2); // not a grey scale
  //FillChar(pcx^.filler,SizeOf(pcx^.filler),0);
  memset(@pcx^.filler, 0, SizeOf(pcx^.filler)); //changed by fab

  // pack the image
  pack := @pcx^.data;

  for I := 0 to height - 1 do
  begin
    for j := 0 to width - 1 do
    begin
      if ((data^ and $C0) <> $C0) then
      begin
        pack^ := data^;

        Inc(Integer(pack));

        Inc(Integer(data));
      end
      else
      begin
        pack^ := $C1;

        Inc(Integer(pack));
        pack^ := data^;

        Inc(Integer(pack));

        Inc(Integer(data));
      end;
    end;

    Inc(Integer(data), rowbytes - width);
  end;

  // write the palette
  pack^ := $0C; // palette ID byte
  Inc(Integer(pack));

  for i := 0 to 768 - 1 do
  begin
    pack^ := palette^;

    Inc(Integer(pack));
    Inc(Integer(palette));
  end;

  // write output file
  length := Integer(pack) - Integer(pcx);

  f := FileCreate(filename);
  if f < 0 then
    ri.Con_Printf(PRINT_ALL, 'Failed to create  %s'#10, filename) //changed by Fab
  else
  begin
    FileWrite(f, pcx^, length);
    FileClose(f);
  end;

  FreeMem(pcx);
end;

procedure R_ScreenShot_f; cdecl;
var
  i: integer;
  pcxname: array[0..80 - 1] of Char;
  checkname: array[0..MAX_OSPATH - 1] of Char;
  palette: array[0..768 - 1] of Byte;
  f: Integer;
begin
  // create the scrnshots directory if it doesn't exist
  Com_sprintf(checkname, SizeOf(checkname), '%s/scrnshot', [ri.FS_Gamedir]);
  MkDir(checkname);
  //
  // find a file name to save it to
  //
  strcpy(pcxname, 'quake00.pcx');

  for i := 0 to 99 do
  begin

    pcxname[5] := Char(i div 10 + Byte('0'));
    pcxname[6] := Char(i mod 10 + Byte('0'));
    Com_sprintf(checkname, sizeof(checkname), '%s/scrnshot/%s', [ri.FS_Gamedir, pcxname]);

    f := fileOpen(checkname, fmOpenRead);
    if f < 0 then
      Break; // file doesn't exist
    Fileclose(f);
  end;
  if i = 100 then
  begin
    ri.Con_Printf(PRINT_ALL, 'R_ScreenShot_f: Couldn''t create a PCX'#10);
    exit;
  end;
  // turn the current 32 bit palette into a 24 bit palette
  for i := 0 to 255 do
  begin
    palette[i * 3 + 0] := sw_state.currentpalette[i * 4 + 0];
    palette[i * 3 + 1] := sw_state.currentpalette[i * 4 + 1];
    palette[i * 3 + 2] := sw_state.currentpalette[i * 4 + 2];
  end;

  //
  // save the pcx file
  //

  WritePCXfile(checkname, vid.buffer, vid.width, vid.height, vid.rowbytes, @palette);

  ri.Con_Printf(PRINT_ALL, 'Wrote %s'#10, checkname);
end;

end.

⌨️ 快捷键说明

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