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

📄 r_poly.pas

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

    Inc(s_spanletvars.izi, s_spanletvars.izistep);
    Inc(Integer(s_spanletvars.pdest), 1);
    Inc(Integer(s_spanletvars.pz), SizeOf(SmallInt));
    Inc(s_spanletvars.s, s_spanletvars.sstep);
    Inc(s_spanletvars.t, s_spanletvars.tstep);

    Dec(s_spanletvars.spancount);
  until not (s_spanletvars.spancount > 0);
end;

{
** R_DrawSpanlet33Stipple
}

procedure R_DrawSpanlet33Stipple;
var
  btemp: cardinal;
  pdest: PByte;
  pz: PSmallInt;
  izi: integer;

  s, t: Integer;
begin
  pdest := s_spanletvars.pdest;
  pz := s_spanletvars.pz;
  izi := s_spanletvars.izi;
  if IntPower(r_polydesc.stipple_parity, (s_spanletvars.v and 1)) > 0 then
  begin
    Inc(Integer(s_spanletvars.pdest), s_spanletvars.spancount);
    Inc(Integer(s_spanletvars.pz), s_spanletvars.spancount * SizeOf(SmallInt));

    if s_spanletvars.spancount = AFFINE_SPANLET_SIZE then
      Inc(s_spanletvars.izi, (s_spanletvars.izistep shl AFFINE_SPANLET_SIZE_BITS))
    else
      Inc(s_spanletvars.izi, (s_spanletvars.izistep * s_spanletvars.izistep));

    if IntPower(r_polydesc.stipple_parity, (s_spanletvars.u and 1)) > 0 then
    begin
      Inc(izi, s_spanletvars.izistep);
      Inc(s_spanletvars.s, s_spanletvars.sstep);
      Inc(s_spanletvars.t, s_spanletvars.tstep);

      Inc(Integer(pdest), 1);
      Inc(Integer(pz), SizeOf(SmallInt));
      Dec(s_spanletvars.spancount);
    end;

    s_spanletvars.sstep := s_spanletvars.sstep * 2;
    s_spanletvars.tstep := s_spanletvars.tstep * 2;

    while s_spanletvars.spancount > 0 do
    begin
      s := _SAR(s_spanletvars.s, 16);
      t := _SAR(s_spanletvars.t, 16);

      btemp := PByte(Integer(s_spanletvars.pbase) + (s) + (t * cachewidth))^;

      if btemp <> 255 then
      begin
        if pz^ <= _SAR(izi, 16) then
          pdest^ := btemp;
      end;

      Inc(izi, s_spanletvars.izistep_times_2);
      Inc(s_spanletvars.s, s_spanletvars.sstep);
      Inc(s_spanletvars.t, s_spanletvars.tstep);

      Inc(Integer(pdest), 2);
      Inc(Integer(pz), 2 * SizeOf(SmallInt));

      Dec(s_spanletvars.spancount, 2);
    end;
  end;
end;

{
** R_DrawSpanlet66Stipple
}

procedure R_DrawSpanlet66Stipple;
var
  btemp: cardinal;
  pdest: PByte;
  pz: PSmallInt;
  izi: integer;
  s, t: Integer;
begin
  pdest := s_spanletvars.pdest;
  pz := s_spanletvars.pz;
  izi := s_spanletvars.izi;

  Inc(Integer(s_spanletvars.pdest), s_spanletvars.spancount);
  Inc(Integer(s_spanletvars.pz), s_spanletvars.spancount * SizeOf(SmallInt));

  if (s_spanletvars.spancount = AFFINE_SPANLET_SIZE) then
    Inc(s_spanletvars.izi, (s_spanletvars.izistep shl AFFINE_SPANLET_SIZE_BITS))
  else
    Inc(s_spanletvars.izi, s_spanletvars.izistep * s_spanletvars.izistep);

  if IntPower(r_polydesc.stipple_parity, (s_spanletvars.v and 1)) <> 0 then
  begin
    if IntPower(r_polydesc.stipple_parity, (s_spanletvars.u and 1)) <> 0 then
    begin
      Inc(izi, s_spanletvars.izistep);
      Inc(s_spanletvars.s, s_spanletvars.sstep);
      Inc(s_spanletvars.t, s_spanletvars.tstep);

      Inc(Integer(pdest), 1);
      Inc(Integer(pz), SizeOf(SmallInt));
      Dec(s_spanletvars.spancount);
    end;

    s_spanletvars.sstep := s_spanletvars.sstep * 2;
    s_spanletvars.tstep := s_spanletvars.tstep * 2;

    while (s_spanletvars.spancount > 0) do
    begin
      s := _SAR(s_spanletvars.s, 16);
      t := _SAR(s_spanletvars.t, 16);

      btemp := PByte(Integer(s_spanletvars.pbase) + (s) + (t * cachewidth))^;

      if btemp <> 255 then
      begin
        if pz^ <= _SAR(izi, 16) then
          pdest^ := btemp;
      end;

      Inc(izi, s_spanletvars.izistep_times_2);
      Inc(s_spanletvars.s, s_spanletvars.sstep);
      Inc(s_spanletvars.t, s_spanletvars.tstep);

      Inc(Integer(pdest), 2);
      Inc(Integer(pz), 2 * SizeOf(SmallInt));

      Dec(s_spanletvars.spancount, 2);
    end;
  end
  else
  begin
    while (s_spanletvars.spancount > 0) do
    begin
      s := _SAR(s_spanletvars.s, 16);
      t := _SAR(s_spanletvars.t, 16);

      btemp := PByte(Integer(s_spanletvars.pbase) + (s) + (t * cachewidth))^;

      if (btemp <> 255) then
      begin
        if pz^ <= _SAR(izi, 16) then
          pdest^ := btemp;
      end;

      Inc(izi, s_spanletvars.izistep);
      Inc(s_spanletvars.s, s_spanletvars.sstep);
      Inc(s_spanletvars.t, s_spanletvars.tstep);

      Inc(Integer(pdest), 1);
      Inc(Integer(pz), SizeOf(SmallInt));

      Dec(s_spanletvars.spancount);
    end;
  end;
end;

{
** R_ClipPolyFace
**
** Clips the winding at clip_verts[clip_current] and changes clip_current
** Throws out the back side
}

function R_ClipPolyFace(nump: integer; pclipplane: clipplane_p): integer;
var
  i, outcount: Integer;
  dists: array[0..MAXWORKINGVERTS + 3 - 1] of Single;
  frac, clipdist: Single;
  pclipnormal: PSingle;
  _in, instep: PSingle;
  outstep, vert2: PSingle;
label
  continue_;
begin
  clipdist := pclipplane^.dist;
  pclipnormal := @pclipplane^.normal;

// calc dists
  if (clip_current <> 0) then
  begin
    _in := @r_clip_verts[1][0]; // Converted from "r_clip_verts[1][0]"
    outstep := @r_clip_verts[0][0]; // Converted from "r_clip_verts[0][0]"
    clip_current := 0;
  end
  else
  begin
    _in := @r_clip_verts[0][0]; // Converted from "r_clip_verts[0][0]"
    outstep := @r_clip_verts[1][0]; // Converted from "r_clip_verts[1][0]"
    clip_current := 1;
  end;

  instep := _in;
  for i := 0 to nump - 1 do
  begin
    dists[i] := DotProduct(vec3_p(instep)^, vec3_p(pclipnormal)^) - clipdist;
    Inc(Integer(instep), SizeOf(vec5_t));
  end;

// handle wraparound case
  dists[nump] := dists[0];
  Move(_in^, instep^, sizeof(vec5_t));

// clip the winding
  instep := _in;
  outcount := 0;

  for i := 0 to nump - 1 do
  begin
    if (dists[i] >= 0) then
    begin
      Move(instep^, outstep^, SizeOf(vec5_t));
      Inc(Integer(outstep), SizeOf(vec5_t));
      Inc(outcount);
    end;

    if (dists[i] = 0) or (dists[i + 1] = 0) then
      goto continue_;

    if (dists[i] > 0) = (dists[i + 1] > 0) then
      goto continue_;

    // split it into a new vertex
    frac := dists[i] / (dists[i] - dists[i + 1]);

    vert2 := PSingle(Integer(instep) + SizeOf(vec5_t));

    vec5_p(outstep)^[0] := vec5_p(instep)^[0] + frac * (vec5_p(vert2)^[0] - vec5_p(instep)^[0]);
    vec5_p(outstep)^[1] := vec5_p(instep)^[1] + frac * (vec5_p(vert2)^[1] - vec5_p(instep)^[1]);
    vec5_p(outstep)^[2] := vec5_p(instep)^[2] + frac * (vec5_p(vert2)^[2] - vec5_p(instep)^[2]);
    vec5_p(outstep)^[3] := vec5_p(instep)^[3] + frac * (vec5_p(vert2)^[3] - vec5_p(instep)^[3]);
    vec5_p(outstep)^[4] := vec5_p(instep)^[4] + frac * (vec5_p(vert2)^[4] - vec5_p(instep)^[4]);

    Inc(Integer(outstep), SizeOf(vec5_t)); // "/" operator has been changed to "div"
    Inc(outcount);

    continue_:
    Inc(Integer(instep), SizeOf(vec5_t));
  end;
  result := outcount;
end;

{
** R_PolygonDrawSpans
}
// PGM - iswater was qboolean. changed to allow passing more flags

procedure R_PolygonDrawSpans(pspan: espan_p; iswater: integer);
var
  count: integer;
  snext, tnext: fixed16_t;
  sdivz, tdivz: single;
  zi, z, du, dv: single;
  spancountminus1: single;
  sdivzspanletstepu: single;
  tdivzspanletstepu: single;
  zispanletstepu: single;
label
  NextSpan;
begin
  s_spanletvars.pbase := cacheblock;

//PGM
  if (iswater and SURF_WARP) <> 0 then
    r_turb_turb := @sintable[(Trunc(r_newrefdef.time * SPEED) and (CYCLE - 1))] // removed innecesary cast
  else
    if (iswater and SURF_FLOWING) <> 0 then
      r_turb_turb := @blanktable;
//PGM

  sdivzspanletstepu := d_sdivzstepu * AFFINE_SPANLET_SIZE;
  tdivzspanletstepu := d_tdivzstepu * AFFINE_SPANLET_SIZE;
  zispanletstepu := d_zistepu * AFFINE_SPANLET_SIZE;

// we count on FP exceptions being turned off to avoid range problems
  s_spanletvars.izistep := Trunc(d_zistepu * $8000 * $10000);
  s_spanletvars.izistep_times_2 := s_spanletvars.izistep * 2;

  s_spanletvars.pz := nil;

  if (pspan^.count = DS_SPAN_LIST_END) then
    exit;

  repeat
    s_spanletvars.pdest := PByte(Integer(d_viewbuffer) + d_scantable[pspan^.v] + pspan^.u);
    s_spanletvars.pz := @PSmallIntArray(d_pzbuffer)^[(Integer(d_zwidth) * pspan^.v) + pspan^.u];
    s_spanletvars.u := pspan^.u;
    s_spanletvars.v := pspan^.v;

    count := pspan^.count;

    if (count <= 0) then
      goto NextSpan;

      // calculate the initial s/z, t/z, 1/z, s, and t and clamp
    du := pspan^.u;
    dv := pspan^.v;

    sdivz := d_sdivzorigin + dv * d_sdivzstepv + du * d_sdivzstepu;
    tdivz := d_tdivzorigin + dv * d_tdivzstepv + du * d_tdivzstepu;

    zi := d_ziorigin + dv * d_zistepv + du * d_zistepu;
    z := $10000 / zi; // prescale to 16.16 fixed-point
      // we count on FP exceptions being turned off to avoid range problems
    s_spanletvars.izi := Trunc(zi * $8000 * $10000);

    s_spanletvars.s := Trunc(sdivz * z) + sadjust;
    s_spanletvars.t := Trunc(tdivz * z) + tadjust;

    if iswater = 0 then
    begin
      if (s_spanletvars.s > bbextents) then
        s_spanletvars.s := bbextents
      else
        if (s_spanletvars.s < 0) then
          s_spanletvars.s := 0;

      if (s_spanletvars.t > bbextentt) then
        s_spanletvars.t := bbextentt
      else
        if (s_spanletvars.t < 0) then
          s_spanletvars.t := 0;
    end;

    repeat
        // calculate s and t at the far end of the span
      if (count >= AFFINE_SPANLET_SIZE) then
        s_spanletvars.spancount := AFFINE_SPANLET_SIZE
      else
        s_spanletvars.spancount := count;

      Dec(count, s_spanletvars.spancount);

      if count <> 0 then
      begin
          // calculate s/z, t/z, zi->fixed s and t at far end of span,
          // calculate s and t steps across span by shifting
        sdivz := sdivz + sdivzspanletstepu;
        tdivz := tdivz + tdivzspanletstepu;
        zi := zi + zispanletstepu;
        z := z + ($10000 / zi); // prescale to 16.16 fixed-point

        snext := Trunc(sdivz * z) + sadjust;
        tnext := Trunc(tdivz * z) + tadjust;

        if iswater = 0 then
        begin
          if (snext > bbextents) then
            snext := bbextents
          else
            if (snext < AFFINE_SPANLET_SIZE) then
              snext := AFFINE_SPANLET_SIZE; // prevent round-off error on <0 steps from
                                             //  from causing overstepping & running off the
                                             //  edge of the texture

          if (tnext > bbextentt) then
            tnext := bbextentt
          else
            if (tnext < AFFINE_SPANLET_SIZE) then
              tnext := AFFINE_SPANLET_SIZE; // guard against round-off error on <0 steps
        end;

        s_spanletvars.sstep := _SAR(snext - s_spanletvars.s, AFFINE_SPANLET_SIZE_BITS);
        s_spanletvars.tstep := _SAR(tnext - s_spanletvars.t, AFFINE_SPANLET_SIZE_BITS);
      end
      else
      begin
          // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
          // can't step off polygon), clamp, calculate s and t steps across
          // span by division, biasing steps low so we don't run off the
          // texture
        spancountminus1 := (s_spanletvars.spancount - 1);
        sdivz := sdivz + (d_sdivzstepu * spancountminus1);
        tdivz := tdivz + (d_tdivzstepu * spancountminus1);
        zi := zi + (d_zistepu * spancountminus1);
        z := $10000 / zi; // prescale to 16.16 fixed-point
        snext := Trunc(sdivz * z) + sadjust;
        tnext := Trunc(tdivz * z) + tadjust;

        if iswater = 0 then
        begin
          if (snext > bbextents) then
            snext := bbextents
          else
            if (snext < AFFINE_SPANLET_SIZE) then
              snext := AFFINE_SPANLET_SIZE; // prevent round-off error on <0 steps from
                                             //  from causing overstepping & running off the
                                             //  edge of the texture

          if (tnext > bbextentt) then
            tnext := bbextentt
          else
            if (tnext < AFFINE_SPANLET_SIZE) then
              tnext := AFFINE_SPANLET_SIZE; // guard against round-off error on <0 steps
        end;

        if (s_spanletvars.spancount > 1) then
        begin
          s_spanletvars.sstep := (snext - s_spanletvars.s) div (s_spanletvars.spancount - 1);
          s_spanletvars.tstep := (tnext - s_spanletvars.t) div (s_spanletvars.spancount - 1);
        end;
      end;

      if iswater <> 0 then
      begin
        s_spanletvars.s := s_spanletvars.s and ((CYCLE shl 16) - 1);
        s_spanletvars.t := s_spanletvars.t and ((CYCLE shl 16) - 1);
      end;

      r_polydesc.drawspanlet;

      s_spanletvars.s := snext;
      s_spanletvars.t := tnext;

    until (count <= 0);

    NextSpan:
    Inc(Integer(pspan), SizeOf(espan_t));

  until (pspan^.count = DS_SPAN_LIST_END);
end;

{
**
** R_PolygonScanLeftEdge
**
** Goes through the polygon and scans the left edge, filling in
** screen coordinate data for the spans
}

procedure R_PolygonScanLeftEdge;
var
  i, v, itop: integer;
  ibottom: integer;
  lmaxindex: integer;
  pvert, pnext: emitpoint_p;
  pspan: espan_p;
  du, dv, vtop: single;
  vbottom, slope: single;
  u, u_step: fixed16_t;
begin
  pspan := s_polygon_spans;
  i := s_minindex;
  if (i = 0) then
    i := r_polydesc.nump;

  lmaxindex := s_maxindex;
  if (lmaxindex = 0) then
    lmaxindex := r_polydesc.nump;

  vtop := q_shared.ceil(emitpoint_arrp(r_polydesc.pverts)^[i].v);

  repeat
    pvert := @emitpoint_arrp(r_polydesc.pverts)^[i];
    pnext := Pointer(Integer(pvert) - SizeOf(emitpoint_t));

    vbottom := q_shared.ceil(pnext^.v);

    if (vtop < vbottom) then
    begin
      du := pnext^.u - pvert^.u;
      dv := pnext^.v - pvert^.v;

      slope := du / dv;
      u_step := trunc(slope * $10000);
      //adjust u to ceil the integer portion
      u := Trunc((pvert^.u + (slope * (vtop - pvert^.v))) * $10000) + ($10000 - 1);
      itop := Trunc(vtop);
      ibottom := Trunc(vbottom);

      for v := itop to ibottom - 1 do
      begin
        pspan^.u := _SAR(u, 16);
        pspan^.v := v;
        Inc(u, u_step);

⌨️ 快捷键说明

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