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

📄 r_edge.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  // must be two bmodels in the same leaf; don't care which is really
  // in front, because they'll never be farthest anyway
    end;

    goto gotposition;

    newtop:
 // emit a span (obscures current top)
    iu := _SAR(edge^.u, 20);

    if (iu > surf2^.last_u) then
    begin
      span := span_p;
      Inc(Integer(span_p), SizeOf(espan_t));
      span^.u := surf2^.last_u;
      span^.count := iu - span^.u;
      span^.v := current_iv;
      span^.pnext := surf2^.spans;
      surf2^.spans := span;
    end;

  // set last_u on the new span
    surf^.last_u := iu;

    gotposition:
 // insert before surf2
    surf^.next := surf2;
    surf^.prev := surf2^.prev;
    surf2^.prev^.next := surf;
    surf2^.prev := surf;
  end;
end;

(*
==============
R_TrailingEdge
==============
*)

procedure R_TrailingEdge(surf: surf_p; edge: edge_p);
var
  span: espan_p;
  iu: Integer;
begin
// don't generate a span if this is an inverted span, with the end
// edge preceding the start edge (that is, we haven't seen the
// start edge yet)
  Dec(surf^.spanstate, 1);
  if (surf^.spanstate = 0) then
  begin
    if (Integer(surf) = Integer(@PSurf_tArray(surfaces)^[1].next)) then
    begin
  // emit a span (current top going away)
      iu := _SAR(edge^.u, 20);
      if (iu > surf^.last_u) then
      begin
        span := span_p;
        Inc(Integer(span_p), SizeOf(espan_t));
        span^.u := surf^.last_u;
        span^.count := iu - span^.u;
        span^.v := current_iv;
        span^.pnext := surf^.spans;
        surf^.spans := span;
      end;

  // set last_u on the surface below
      surf^.next^.last_u := iu;
    end;

    surf^.prev^.next := surf^.next;
    surf^.next^.prev := surf^.prev;
  end;
end;

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

procedure R_LeadingEdge(edge: edge_p);
label
  gotposition;
label
  newtop;
label
  continue_search;
var
  span: espan_p;
  surf: surf_p;
  surf2: surf_p;
  iu: Integer;
  fu, newzi: Single;
  testzi: Single;
  newzitop: Single;
  newzibottom: Single;
begin
  if (edge^.surfs[1] <> 0) then
  begin
 // it's adding a new surface in, so find the correct place
    surf := @PSurf_tArray(surfaces)^[1];

 // don't start a span if this is an inverted span, with the end
 // edge preceding the start edge (that is, we've already seen the
 // end edge)
    Inc(surf^.spanstate, 1);
    if (surf^.spanstate = 1) then
    begin
      surf2 := PSurf_tArray(surfaces)^[1].next;

      if (surf^.key < surf2^.key) then
        goto newtop;

  // if it's two surfaces on the same plane, the one that's already
  // active is in front, so keep going unless it's a bmodel
      if ((surf^.insubmodel) and (surf^.key = surf2^.key)) then
      begin
   // must be two bmodels in the same leaf; sort on 1/z
        fu := edge^.u;
        fu := (fu - $FFFFF) * (1.0 / $100000);
        newzi := surf^.d_ziorigin + fv * surf^.d_zistepv + fu * surf^.d_zistepu;
        newzibottom := newzi * 0.99;

        testzi := surf2^.d_ziorigin + fv * surf2^.d_zistepv + fu * surf2^.d_zistepu;

        if (newzibottom >= testzi) then
        begin
          goto newtop;
        end;

        newzitop := newzi * 1.01;
        if (newzitop >= testzi) then
        begin
          if (surf^.d_zistepu >= surf2^.d_zistepu) then
          begin
            goto newtop;
          end;
        end;
      end;

      continue_search:

      repeat
        surf2 := surf2^.next;
      until (surf^.key <= surf2^.key);

      if (surf^.key = surf2^.key) then
      begin
   // if it's two surfaces on the same plane, the one that's already
   // active is in front, so keep going unless it's a bmodel
        if not (surf^.insubmodel) then
          goto continue_search;

   // must be two bmodels in the same leaf; sort on 1/z
        fu := edge^.u;
        fu := (fu - $FFFFF) * (1.0 / $100000);
        newzi := surf^.d_ziorigin + fv * surf^.d_zistepv + fu * surf^.d_zistepu;
        newzibottom := newzi * 0.99;

        testzi := surf2^.d_ziorigin + fv * surf2^.d_zistepv + fu * surf2^.d_zistepu;

        if (newzibottom >= testzi) then
        begin
          goto gotposition;
        end;

        newzitop := newzi * 1.01;
        if (newzitop >= testzi) then
        begin
          if (surf^.d_zistepu >= surf2^.d_zistepu) then
          begin
            goto gotposition;
          end;
        end;

        goto continue_search;
      end;

      goto gotposition;

      newtop:
  // emit a span (obscures current top)
      iu := _SAR(edge^.u, 20);

      if (iu > surf2^.last_u) then
      begin
        span := span_p;
        Inc(Integer(span_p), SizeOf(espan_t));
        span^.u := surf2^.last_u;
        span^.count := iu - span^.u;
        span^.v := current_iv;
        span^.pnext := surf2^.spans;
        surf2^.spans := span;
      end;

   // set last_u on the new span
      surf^.last_u := iu;

      gotposition:
  // insert before surf2
      surf^.next := surf2;
      surf^.prev := surf2^.prev;
      surf2^.prev^.next := surf;
      surf2^.prev := surf;
    end;
  end;
end;

(*
==============
R_GenerateSpans
==============
*)

procedure R_GenerateSpans;
var
  edge: edge_p;
  surf: surf_p;
begin
// clear active surfaces to just the background surface
  PSurf_tArray(surfaces)^[1].next := @PSurf_tArray(surfaces)^[1];
  PSurf_tArray(surfaces)^[1].prev := @PSurf_tArray(surfaces)^[1];
  PSurf_tArray(surfaces)^[1].last_u := edge_head_u_shift20;

// generate spans
  edge := edge_head.next;
  while (Integer(edge) <> Integer(@edge_tail)) do
//	for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next) then
  begin
    if (edge^.surfs[0] <> 0) then
    begin
  // it has a left surface, so a surface is going away for this span
      surf := @PSurf_tArray(surfaces)^[edge^.surfs[0]];
      R_TrailingEdge(surf, edge);
      if (edge^.surfs[1] = 0) then
      begin
        edge := edge^.next;
        continue;
      end;
    end;
    R_LeadingEdge(edge);
    edge := edge^.next;
  end;
  R_CleanupSpan;
end;
{$ENDIF} // !id386

(*
==============
R_GenerateSpansBackward
==============
*)

procedure R_GenerateSpansBackward;
var
  edge: edge_p;
  surf: surf_p;
begin
// clear active surfaces to just the background surface
  PSurf_tArray(surfaces)^[1].next := @PSurf_tArray(surfaces)^[1];
  PSurf_tArray(surfaces)^[1].prev := @PSurf_tArray(surfaces)^[1];
  PSurf_tArray(surfaces)^[1].last_u := edge_head_u_shift20;

// generate spans
  edge := edge_head.next;
  while (Integer(edge) <> Integer(@edge_tail)) do
//	for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next) then
  begin
    if (edge^.surfs[0] <> 0) then
    begin
  // it has a left surface, so a surface is going away for this span
      surf := @PSurf_tArray(surfaces)^[edge^.surfs[0]];
      R_TrailingEdge(surf, edge);
    end;
    if (edge^.surfs[1] <> 0) then
      R_LeadingEdgeBackwards(edge);
    edge := edge^.next;
  end;
  R_CleanupSpan;
end;

(*
==============
R_ScanEdges

Input:
newedges[] array
 this has links to edges, which have links to surfaces

Output:
Each surface has a linked list of its visible spans
==============
*)

procedure R_ScanEdges;
var
  iv, bottom: Integer;
  basespans: array[0..(MAXSPANS * sizeof(espan_t) + CACHE_SIZE) - 1] of Byte;
  basespan_p: espan_p;
  s: surf_p;
begin
//	basespan_p = (espan_t *)((long)(basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
  basespan_p := espan_p(Integer(@basespans[(CACHE_SIZE - 1) * sizeof(espan_t)]) and ($FFFFFFFF xor (CACHE_SIZE - 1)));

//	max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width];
  max_span_p := @PEspan_tArray(basespan_p)^[MAXSPANS - r_refdef.vrect.width];

  span_p := basespan_p;

// clear active edges to just the background edges around the whole screen
// FIXME: most of this only needs to be set up once
  edge_head.u := _SAL(r_refdef.vrect.x, 20);
  edge_head_u_shift20 := _SAR(edge_head.u, 20);
  edge_head.u_step := 0;
  edge_head.prev := nil;
  edge_head.next := @edge_tail;
  edge_head.surfs[0] := 0;
  edge_head.surfs[1] := 1;

  edge_tail.u := _SAL(r_refdef.vrectright, 20) + $FFFFF;
  edge_tail_u_shift20 := _SAR(edge_tail.u, 20);
  edge_tail.u_step := 0;
  edge_tail.prev := @edge_head;
  edge_tail.next := @edge_aftertail;
  edge_tail.surfs[0] := 1;
  edge_tail.surfs[1] := 0;

  edge_aftertail.u := -1; // force a move
  edge_aftertail.u_step := 0;
  edge_aftertail.next := @edge_sentinel;
  edge_aftertail.prev := @edge_tail;

// FIXME: do we need this now that we clamp x in r_draw.c?
  edge_sentinel.u := 125 shl 24; //2000 shl 24;		// make sure nothing sorts past this
  edge_sentinel.prev := @edge_aftertail;

//
// process all scan lines
//
  bottom := r_refdef.vrectbottom - 1;

//	for (iv=r_refdef.vrect.y ; iv<bottom ; iv++) do
  for iv := r_refdef.vrect.y to bottom - 1 do
  begin
    current_iv := iv;
    fv := iv;

 // mark that the head (background start) span is pre-included
    PSurf_tArray(surfaces)^[1].spanstate := 1;
    if (newedges[iv] <> nil) then
    begin
      R_InsertNewEdges(newedges[iv], edge_head.next);
    end;

    pdrawfunc;

 // flush the span list if we can't be sure we have enough spans left for
 // the next scan
    if (Integer(span_p) > Integer(max_span_p)) then
    begin
      D_DrawSurfaces;

  // clear the surface span pointers

//			for (s = &surfaces[1] ; s<surface_p ; s++) do
      s := @PSurf_tArray(surfaces)^[1];
      while (Integer(s) < Integer(surface_p)) do
      begin
        s^.spans := nil;
        Inc(Integer(s), SizeOf(surf_t));
      end;
      span_p := basespan_p;
    end;

    if (removeedges[iv] <> nil) then
      R_RemoveEdges(removeedges[iv]);

    if (Integer(edge_head.next) <> Integer(@edge_tail)) then
      R_StepActiveU(edge_head.next);
  end;

// do the last scan (no need to step or sort or remove on the last scan)
  iv := bottom;
  current_iv := iv;
  fv := iv;

// mark that the head (background start) span is pre-included
  PSurf_tArray(surfaces)^[1].spanstate := 1;

  if (newedges[iv] <> nil) then
    R_InsertNewEdges(newedges[iv], edge_head.next);

  pdrawfunc;

// draw whatever's left in the span list
  D_DrawSurfaces;
end;

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

SURFACE FILLING

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

var
  pface: msurface_p;
  pcurrentcache: surfcache_p;
  transformed_modelorg: vec3_t;
  world_transformed_modelorg: vec3_t;
  local_modelorg: vec3_t;

⌨️ 快捷键说明

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