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

📄 r_main.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:

  r_cnumsurfs := Trunc(sw_maxsurfs^.value);

  if (r_cnumsurfs <= MINSURFACES) then
    r_cnumsurfs := MINSURFACES;

  if (r_cnumsurfs > NUMSTACKSURFACES) then
  begin
    surfaces := AllocMem(r_cnumsurfs * sizeof(surf_t));
    surface_p := surfaces;
    surf_max := surf_p(Integer(surfaces) + (r_cnumsurfs * sizeof(surf_t)));
    r_surfsonstack := false;
 // surface 0 doesn't really exist; it's just a dummy because index 0
 // is used to indicate no edge attached to surface
    Dec(Integer(surfaces), SizeOf(surf_t));
    R_SurfacePatch;
  end
  else
  begin
    r_surfsonstack := true;
  end;

  r_maxedgesseen := 0;
  r_maxsurfsseen := 0;

  r_numallocatededges := Trunc(sw_maxedges^.value);

  if (r_numallocatededges < MINEDGES) then
    r_numallocatededges := MINEDGES;

  if (r_numallocatededges <= NUMSTACKEDGES) then
  begin
    auxedges := nil;
  end
  else
  begin
    auxedges := AllocMem(r_numallocatededges * sizeof(edge_t));
  end;
end;

(*
===============
R_MarkLeaves

Mark the leaves and nodes that are in the PVS for the current
cluster
===============
*)

procedure R_MarkLeaves;
var
  vis: PByte;
  node: mnode_p;
  i: Integer;
  leaf: mleaf_p;
  cluster: Integer;
begin
  if ((r_oldviewcluster = r_viewcluster) and (r_novis^.value = 0.0) and (r_viewcluster <> -1)) then
    Exit;

 // development aid to let you run around and see exactly where
 // the pvs ends
  if (sw_lockpvs^.value <> 0.0) then
    Exit;

  Inc(r_visframecount);
  r_oldviewcluster := r_viewcluster;

  if (r_novis^.value <> 0.0) or (r_viewcluster = -1) or (r_worldmodel^.vis = nil) then
  begin
  // mark everything
    for i := 0 to r_worldmodel^.numleafs - 1 do
      mleaf_arrp(r_worldmodel^.leafs)^[i].visframe := r_visframecount;
    for i := 0 to r_worldmodel^.numnodes - 1 do
      mnode_arrp(r_worldmodel^.nodes)^[i].visframe := r_visframecount;
    Exit;
  end;

  vis := Mod_ClusterPVS(r_viewcluster, r_worldmodel);

  leaf := r_worldmodel^.leafs;
  for I := 0 to r_worldmodel^.numleafs - 1 do
  begin
    cluster := leaf^.cluster;
    if (cluster = -1) then
    begin
      Inc(Integer(leaf), Sizeof(mleaf_t));
      continue;
    end;
    if (PByteArray(vis)^[cluster shr 3] and (1 shl (cluster and 7))) <> 0 then
    begin
      node := mnode_p(leaf);
      repeat
        if (node^.visframe = r_visframecount) then
          break;
        node^.visframe := r_visframecount;
        node := node^.parent;
      until (node = nil);
    end;
    Inc(Cardinal(leaf), Sizeof(mleaf_t));
  end;
end;

(*
** R_DrawNullModel
**
** IMPLEMENT THIS!
*)

procedure R_DrawNullModel;
begin
end;

(*
=============
R_DrawEntitiesOnList
=============
*)

procedure R_DrawEntitiesOnList;
var
  i: Integer;
  translucent_entities: qboolean;
begin
  translucent_entities := False;
  if (r_drawentities^.value = 0.0) then
    Exit;

 // all bmodels have already been drawn by the edge list
  for I := 0 to r_newrefdef.num_entities - 1 do
  begin
    currententity := @entity_arrp(r_newrefdef.entities)^[i];

    if (currententity^.flags and RF_TRANSLUCENT) <> 0 then
    begin
      translucent_entities := true;
      continue;
    end;

    if (currententity^.flags and RF_BEAM) <> 0 then
    begin
      modelorg[0] := -r_origin[0];
      modelorg[1] := -r_origin[1];
      modelorg[2] := -r_origin[2];
      VectorCopy(vec3_origin, r_entorigin);
      R_DrawBeam(currententity);
    end
    else
    begin
      currentmodel := currententity^.model;
      if (currentmodel = nil) then
      begin
        R_DrawNullModel;
        continue;
      end;
      VectorCopy(vec3_p(@currententity^.origin)^, r_entorigin);
      VectorSubtract(r_origin, r_entorigin, modelorg);

      case (currentmodel^._type) of
        mod_sprite:
          R_DrawSprite;
        mod_alias:
          R_AliasDrawModel;
      end;
    end
  end;

  if (not translucent_entities) then
    Exit;

  for I := 0 to r_newrefdef.num_entities - 1 do
  begin
    currententity := @entity_arrp(r_newrefdef.entities)^[i];

    if ((currententity^.flags and RF_TRANSLUCENT) = 0) then
      continue;

    if (currententity^.flags and RF_BEAM) <> 0 then
    begin
      modelorg[0] := -r_origin[0];
      modelorg[1] := -r_origin[1];
      modelorg[2] := -r_origin[2];
      VectorCopy(vec3_origin, r_entorigin);
      R_DrawBeam(currententity);
    end
    else
    begin
      currentmodel := currententity^.model;
      if (currentmodel = nil) then
      begin
        R_DrawNullModel;
        continue;
      end;
      VectorCopy(vec3_p(@currententity^.origin)^, r_entorigin);
      VectorSubtract(r_origin, r_entorigin, modelorg);

      case (currentmodel^._type) of
        mod_sprite:
          R_DrawSprite;
        mod_alias:
          R_AliasDrawModel;
      end;
    end;
  end;
end;

(*
=============
R_BmodelCheckBBox
=============
*)

function R_BmodelCheckBBox(minmaxs: PSingle): Integer;
var
  i: Integer;
  pindex: PInteger;
  clipflags: Integer;
  acceptpt: vec3_t;
  rejectpt: vec3_t;
  d: Single;
begin
  clipflags := 0;

  for I := 0 to 4 - 1 do
  begin
 // generate accept and reject points
 // FIXME: do with fast look-ups or integer tests based on the sign bit
 // of the floating point values

    pindex := pfrustum_indexes[i];

    rejectpt[0] := PSingleArray(minmaxs)^[PIntegerArray(pindex)^[0]];
    rejectpt[1] := PSingleArray(minmaxs)^[PIntegerArray(pindex)^[1]];
    rejectpt[2] := PSingleArray(minmaxs)^[PIntegerArray(pindex)^[2]];

    d := DotProduct(rejectpt, view_clipplanes[i].normal);
    d := d - view_clipplanes[i].dist;

    if (d <= 0) then
    begin
      Result := BMODEL_FULLY_CLIPPED;
      Exit;
    end;

    acceptpt[0] := PSingleArray(minmaxs)^[PIntegerArray(pindex)^[3 + 0]];
    acceptpt[1] := PSingleArray(minmaxs)^[PIntegerArray(pindex)^[3 + 1]];
    acceptpt[2] := PSingleArray(minmaxs)^[PIntegerArray(pindex)^[3 + 2]];

    d := DotProduct(acceptpt, view_clipplanes[i].normal);
    d := d - view_clipplanes[i].dist;

    if (d <= 0) then
      clipflags := clipflags or (1 shl i);
  end;
  Result := clipflags;
end;

(*
===================
R_FindTopnode

Find the first node that splits the given box
===================
*)

function R_FindTopnode(var mins: vec3_t; var maxs: vec3_t): mnode_p;
var
  splitplane: mplane_p;
  sides: Integer;
  node: mnode_p;
begin
  node := r_worldmodel^.nodes;

  while (True) do
  begin
    if (node^.visframe <> r_visframecount) then
    begin
      Result := nil; // not visible at all
      Exit;
    end;

    if (node^.contents <> CONTENTS_NODE) then
    begin
      if (node^.contents <> CONTENTS_SOLID) then
      begin
        Result := node; // we've reached a non-solid leaf, so it's
        Exit; //  visible and not BSP clipped
      end;
      Result := nil; // in solid, so not visible
      Exit;
    end;

    splitplane := node^.plane;
    sides := BOX_ON_PLANE_SIDE(mins, maxs, cplane_p(splitplane));

    if (sides = 3) then
    begin
      Result := node; // this is the splitter
      Exit;
    end;
 // not split yet; recurse down the contacted side
    if (sides and 1) = 1 then
      node := node^.children[0]
    else
      node := node^.children[1];
  end;
end;

(*
=============
RotatedBBox

Returns an axially aligned box that contains the input box at the given rotation
=============
*)

procedure RotatedBBox(var mins: vec3_t; var maxs: vec3_t; var angles: vec3_t; var tmins: vec3_t; var tmaxs: vec3_t);
var
  tmp, v: vec3_t;
  i, j: Integer;
  _forward: vec3_t;
  right: vec3_t;
  up: vec3_t;
begin
  if ((angles[0] = 0.0) and (angles[1] = 0.0) and (angles[2] = 0.0)) then
  begin
    VectorCopy(mins, tmins);
    VectorCopy(maxs, tmaxs);
    Exit;
  end;

  for I := 0 to 2 do
  begin
    tmins[i] := 99999;
    tmaxs[i] := -99999;
  end;

  AngleVectors(angles, @_forward, @right, @up);

  for I := 0 to 7 do
  begin
    if (i and 1) = 1 then
      tmp[0] := mins[0]
    else
      tmp[0] := maxs[0];

    if (i and 2) = 2 then
      tmp[1] := mins[1]
    else
      tmp[1] := maxs[1];

    if (i and 4) = 4 then
      tmp[2] := mins[2]
    else
      tmp[2] := maxs[2];

    VectorScale(_forward, tmp[0], v);
    VectorMA(v, -tmp[1], right, v);
    VectorMA(v, tmp[2], up, v);

    for j := 0 to 2 do
    begin
      if (v[j] < tmins[j]) then
        tmins[j] := v[j];
      if (v[j] > tmaxs[j]) then
        tmaxs[j] := v[j];
    end;
  end;
end;

(*
=============
R_DrawBEntitiesOnList
=============
*)

procedure R_DrawBEntitiesOnList;
var
  i, clipflags: Integer;
  oldorigin: vec3_t;
  mins, maxs: vec3_t;
  minmaxs: array[0..6 - 1] of Single;
  topnode: mnode_p;
begin
  if (r_drawentities^.value = 0.0) then
    Exit;

  VectorCopy(modelorg, oldorigin);
  insubmodel := true;
  r_dlightframecount := r_framecount;

  for I := 0 to r_newrefdef.num_entities - 1 do
  begin
    currententity := @entity_arrp(r_newrefdef.entities)^[i];
    currentmodel := currententity^.model;
    if (currentmodel = nil) then
      continue;
    if (currentmodel^.nummodelsurfaces = 0) then
      continue; // clip brush only
    if (currententity^.flags and RF_BEAM) = RF_BEAM then
      continue;
    if (currentmodel^._type <> mod_brush) then
      continue;
 // see if the bounding box lets us trivially reject, also sets
 // trivial accept status
    RotatedBBox(currentmodel^.mins, currentmodel^.maxs, vec3_p(@currententity^.angles)^, mins, maxs);
    VectorAdd(mins, vec3_p(@currententity^.origin)^, vec3_p(@minmaxs)^);
    VectorAdd(maxs, vec3_p(@currententity^.origin)^, vec3_p(@minmaxs[3])^);

    clipflags := R_BmodelCheckBBox(@minmaxs[0]);
    if (clipflags = BMODEL_FULLY_CLIPPED) then
      continue; // off the edge of the screen

    topnode := R_FindTopnode(vec3_p(@minmaxs)^, vec3_p(@minmaxs[3])^);
    if (topnode = nil) then
      continue; // no part in a visible leaf

    VectorCopy(vec3_p(@currententity^.origin)^, r_entorigin);
    VectorSubtract(r_origin, r_entorigin, modelorg);

    r_pcurrentvertbase := currentmodel^.vertexes;

 // FIXME: stop transforming twice
    R_RotateBmodel;

 // calculate dynamic lighting for bmodel
    R_PushDlights(currentmodel);

    if (topnode^.contents = CONTENTS_NODE) then
    begin
  // not a leaf; has to be clipped to the world BSP
      r_clipflags := clipflags;
      R_DrawSolidClippedSubmodelPolygons(currentmodel, topnode);
    end
    else
    begin
  // falls entirely in one leaf, so we just put all the
  // edges in the edge list and let 1/z sorting handle
  // drawing order
      R_DrawSubmodelPolygons(currentmodel, clipflags, topnode);
    end;

 // put back world rotation and frustum clipping
 // FIXME: R_RotateBmodel should just work off base_vxx
    VectorCopy(base_vpn, vpn);
    VectorCopy(base_vup, vup);
    VectorCopy(base_vright, vright);
    VectorCopy(oldorigin, modelorg);
    R_TransformFrustum;
  end;
  insubmodel := false;
end;

(*
================
R_EdgeDrawing
================
*)

procedure R_EdgeDrawing;
var
  ledges  : array[0..(NUMSTACKEDGES+Trunc((CACHE_SIZE-1) / sizeof(edge_t)))] of edge_t;
  lsurfs  : array[0..(NUMSTACKSURFACES+Trunc((CACHE_SIZE-1) / sizeof(surf_t)))] of surf_t;
begin
(*********
CODEFUSION:
  Somewhere in here the walls are not drawn.
**********)
  if (r_newrefdef.rdflags and RDF_NOWORLDMODEL) <> 0 then
    Exit;

  if (auxedges <> nil) then
  begin
    r_edges := auxedges;
  end
  else
  begin
    r_edges := edge_p((Cardinal(@ledges[0])+CACHE_SIZE-1) and (not Cardinal(CACHE_SIZE-1)));
  end;

  if (r_surfsonstack) then
  begin
    surfaces := surf_p((Cardinal(@lsurfs[0])+CACHE_SIZE-1) and (not Cardinal(CACHE_SIZE-1)));
    surf_max := surf_p(Integer(surfaces)+(r_cnumsurfs*SizeOf(surf_t)));
  // surface 0 doesn't really exist; it's just a dummy because index 0
  // is used to indicate no edge attached to surface
    Dec(Integer(surfaces), Sizeof(surf_t));
    R_SurfacePatch;
  end;
  R_BeginEdgeFrame;

  if (r_dspeeds^.value <> 0.0) then
  begin
    rw_time1 := Sys_Milliseconds;
  end;

  R_RenderWorld;

  if (r_dspeeds^.value <> 0.0) then
  begin
    rw_time2 := Sys_Milliseconds;
    db_time1 := rw_time2;
  end;

  R_DrawBEntitiesOnList;

  if (r_dspeeds^.value <> 0.0) then
  begin
    db_time2 := Sys_Milliseconds;
    se_time1 := db_time2;
  end;
  R_ScanEdges;
end;

⌨️ 快捷键说明

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