📄 r_scan.pas
字号:
//r_turb_pbase = (unsigned char *)cacheblock;
r_turb_pbase := cacheblock;
sdivz16stepu := d_sdivzstepu * 16;
tdivz16stepu := d_tdivzstepu * 16;
zi16stepu := d_zistepu * 16;
//do
repeat
//r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
// (r_screenwidth * pspan->v) + pspan->u);
r_turb_pdest := @PByteArray(d_viewbuffer)^[(r_screenwidth * pspan^.v) + pspan^.u];
count := pspan^.count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
//du = (float)pspan->u;
//dv = (float)pspan->v;
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 = (float)0x10000 / zi; // prescale to 16.16 fixed-point
z := $10000 / zi; { prescale to 16.16 fixed-point }
//r_turb_s = (int)(sdivz * z) + sadjust;
r_turb_s := Trunc(sdivz * z) + sadjust;
if (r_turb_s > bbextents) then
r_turb_s := bbextents
else
if (r_turb_s < 0) then
r_turb_s := 0;
//r_turb_t = (int)(tdivz * z) + tadjust;
r_turb_t := Round(tdivz * z) + tadjust;
if (r_turb_t > bbextentt) then
r_turb_t := bbextentt
else
if (r_turb_t < 0) then
r_turb_t := 0;
//do
repeat
// calculate s and t at the far end of the span
if (count >= 16) then
r_turb_spancount := 16
else
r_turb_spancount := count;
//count -= r_turb_spancount;
count := count - r_turb_spancount;
//if (count)
if Boolean(count) 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 + sdivz16stepu;
tdivz := tdivz + tdivz16stepu;
zi := zi + zi16stepu;
//z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
z := $10000 / zi; // prescale to 16.16 fixed-point
//snext = (int)(sdivz * z) + sadjust;
snext := Round(sdivz * z) + sadjust;
if (snext > bbextents) then
snext := bbextents
else
if (snext < 16) then
snext := 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
//tnext = (int)(tdivz * z) + tadjust;
tnext := Round(tdivz * z) + tadjust;
if (tnext > bbextentt) then
tnext := bbextentt
else
if (tnext < 16) then
tnext := 16; // guard against round-off error on <0 steps
//r_turb_sstep = (snext - r_turb_s) >> 4;
//r_turb_tstep = (tnext - r_turb_t) >> 4;
r_turb_sstep := _SAR((snext - r_turb_s), 4);
r_turb_tstep := _SAR((tnext - r_turb_t), 4);
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 = (float)(r_turb_spancount - 1);
spancountminus1 := (r_turb_spancount - 1);
sdivz := sdivz + d_sdivzstepu * spancountminus1;
tdivz := tdivz + d_tdivzstepu * spancountminus1;
zi := zi + d_zistepu * spancountminus1;
//z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
z := $10000 / zi; { prescale to 16.16 fixed-point }
//snext = (int)(sdivz * z) + sadjust;
snext := Round(sdivz * z) + sadjust;
if (snext > bbextents) then
snext := bbextents
else
if (snext < 16) then
snext := 16; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
//tnext = (int)(tdivz * z) + tadjust;
tnext := Round(tdivz * z) + tadjust;
if (tnext > bbextentt) then
tnext := bbextentt
else
if (tnext < 16) then
tnext := 16; // guard against round-off error on <0 steps
if (r_turb_spancount > 1) then
begin
//r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
//r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
r_turb_sstep := (snext - r_turb_s) div (r_turb_spancount - 1);
r_turb_tstep := (tnext - r_turb_t) div (r_turb_spancount - 1);
end
end;
//r_turb_s = r_turb_s & ((CYCLE<<16)-1);
//r_turb_t = r_turb_t & ((CYCLE<<16)-1);
r_turb_s := r_turb_s and ((CYCLE shl 16) - 1);
r_turb_t := r_turb_t and ((CYCLE shl 16) - 1);
D_DrawTurbulent8Span;
r_turb_s := snext;
r_turb_t := tnext;
until not (count > 0);
//while (count > 0);
pspan := pspan.pnext;
until not (pspan <> nil);
//while ((pspan = pspan->pnext) != NULL);
end;
//PGM
//====================
{$IFNDEF id386}
(*
=============
D_DrawSpans16
FIXME: actually make this subdivide by 16 instead of 8!!!
=============
*)
//void D_DrawSpans16( espan_t *pspan)
procedure D_DrawSpans16(pspan: espan_p);
var
count: Integer;
spancount: Integer;
s, t, snext: fixed16_t;
tnext, sstep: fixed16_t;
tstep: fixed16_t;
sdivz, tdivz: Single;
zi, z, du, dv: Single;
spancountminus1: Single;
sdivz8stepu: Single;
tdivz8stepu: Single;
zi8stepu: Single;
pbase, pdest: PByte;
ts, tt: fixed16_t;
begin
sstep := 0; // keep compiler happy
tstep := 0; // ditto
//pbase = (unsigned char *)cacheblock;
pbase := PByte(cacheblock);
sdivz8stepu := d_sdivzstepu * 8;
tdivz8stepu := d_tdivzstepu * 8;
zi8stepu := d_zistepu * 8;
//do
repeat
//pdest = (unsigned char *)((byte *)d_viewbuffer +
// (r_screenwidth * pspan->v) + pspan->u);
pdest := @PByteArray(d_viewbuffer)^[(r_screenwidth * pspan^.v) + pspan^.u];
count := pspan^.count;
// calculate the initial s/z, t/z, 1/z, s, and t and clamp
//du = (float)pspan->u;
//dv = (float)pspan->v;
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 = (float)0x10000 / zi; // prescale to 16.16 fixed-point
z := $10000 / zi; // prescale to 16.16 fixed-point
//s = (int)(sdivz * z) + sadjust;
s := Trunc(sdivz * z) + sadjust;
if (s > bbextents) then
s := bbextents
else
if (s < 0) then
s := 0;
//t = (int)(tdivz * z) + tadjust;
t := Trunc(tdivz * z) + tadjust;
if (t > bbextentt) then
t := bbextentt
else
if (t < 0) then
t := 0;
//do
repeat
// calculate s and t at the far end of the span
if (count >= 8) then
spancount := 8
else
spancount := count;
//count -= spancount;
count := count - spancount;
//if (count)
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 + sdivz8stepu;
tdivz := tdivz + tdivz8stepu;
zi := zi + zi8stepu;
//z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
z := $10000 / zi; // prescale to 16.16 fixed-point
//snext = (int)(sdivz * z) + sadjust;
snext := Trunc(sdivz * z) + sadjust;
if (snext > bbextents) then
snext := bbextents
else
if (snext < 8) then
snext := 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
//tnext = (int)(tdivz * z) + tadjust;
tnext := Trunc(tdivz * z) + tadjust;
if (tnext > bbextentt) then
tnext := bbextentt
else
if (tnext < 8) then
tnext := 8; // guard against round-off error on <0 steps
//sstep = (snext - s) >> 3;
//tstep = (tnext - t) >> 3;
sstep := _SAR((snext - s), 3); //(snext - s) div 8;//shr 3;
tstep := _SAR((tnext - t), 3);
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 = (float)(spancount - 1);
spancountminus1 := (spancount - 1);
sdivz := sdivz + d_sdivzstepu * spancountminus1;
tdivz := tdivz + d_tdivzstepu * spancountminus1;
zi := zi + d_zistepu * spancountminus1;
//z = (float)0x10000 / zi; // prescale to 16.16 fixed-point
z := $10000 / zi; { prescale to 16.16 fixed-point }
//snext = (int)(sdivz * z) + sadjust;
snext := Trunc(sdivz * z) + sadjust;
if (snext > bbextents) then
snext := bbextents
else
if (snext < 8) then
snext := 8; // prevent round-off error on <0 steps from
// from causing overstepping & running off the
// edge of the texture
//tnext = (int)(tdivz * z) + tadjust;
tnext := Trunc(tdivz * z) + tadjust;
if (tnext > bbextentt) then
tnext := bbextentt
else
if (tnext < 8) then
tnext := 8; // guard against round-off error on <0 steps
if (spancount > 1) then
begin
//sstep = (snext - s) / (spancount - 1);
//tstep = (tnext - t) / (spancount - 1);
sstep := trunc((snext - s) / (spancount - 1));
tstep := trunc((tnext - t) / (spancount - 1));
end
end;
//do
repeat
//*pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
ts := _SAR(s, 16);
tt := _SAR(t, 16);
pdest^ := PByte(Integer(pbase) + ts + tt * cachewidth)^;
Inc(Integer(pdest));
s := s + sstep;
t := t + tstep;
Dec(spancount);
until (spancount <= 0);
s := snext;
t := tnext;
until not (count > 0);
//while (count > 0);
pspan := pspan^.pnext;
until (pspan = nil);
//while ((pspan = pspan->pnext) != NULL);
end;
{$ENDIF}
{$IFNDEF id386}
(*
=============
D_DrawZSpans
=============
*)
//void D_DrawZSpans (espan_t *pspan)
procedure D_DrawZSpans(pspan: espan_p);
var
count: Integer;
doublecount: Integer;
izistep: Integer;
izi: Integer;
pdest: PSmallInt;
ltemp: Cardinal;
zi: Single;
du, dv: Single;
begin
// FIXME: check for clamping/range problems
// we count on FP exceptions being turned off to avoid range problems
Assert(pspan <> nil);
//izistep = (int)(d_zistepu * 0x8000 * 0x10000);
izistep := Trunc(d_zistepu * $8000 * $10000);
//do
repeat
//pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
pdest := @PSmallIntArray(d_pzbuffer)^[(Integer(d_zwidth) * pspan^.v) + pspan^.u];
// pdest := PSmallInt(Integer(d_pzbuffer)+(((Integer(d_zwidth)*pspan^.v)+pspan^.u)*SizeOf(SmallInt)));
count := pspan^.count;
// calculate the initial 1/z
du := pspan^.u;
dv := pspan^.v;
zi := d_ziorigin + dv * d_zistepv + du * d_zistepu;
// we count on FP exceptions being turned off to avoid range problems
//izi = (int)(zi * 0x8000 * 0x10000);
izi := Trunc(zi * $8000 * $10000);
//if ((long)pdest & 0x02)
if (Cardinal(pdest) and $02) <> 0 then
begin
//*pdest++ = (short)(izi >> 16);
pdest^ := _SAR(izi, 16); //(izi shr 16);
Inc(Integer(pdest), SizeOf(pdest^));
izi := izi + izistep;
Dec(count);
end;
//if ((doublecount = count >> 1) > 0)
doublecount := count shr 1;
if (doublecount) > 0 then
//do
repeat
ltemp := izi shr 16; // need to clear upper part (16 high bits).
izi := izi + izistep;
//ltemp |= izi & 0xFFFF0000;
ltemp := (ltemp and $FFFF) or (Cardinal(izi) and $FFFF0000);
izi := izi + izistep;
//*(int *)pdest = ltemp;
PCardinal(pdest)^ := ltemp;
//pdest += 2;
Inc(Integer(pdest), SizeOf(Cardinal));
Dec(doublecount);
until (doublecount = 0);
//while (--doublecount > 0);
//if (count & 1)
if (count and 1) <> 0 then
pdest^ := _SAR(izi, 16);
//*pdest = (short)(izi >> 16);
pspan := pspan^.pnext;
until (pspan = nil);
//while ((pspan = pspan->pnext) != NULL);
end;
{$ENDIF}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -