📄 r_polyse.pas
字号:
r_p0[5] := aliastriangleparms.a^.zi; // iz
r_p1[0] := aliastriangleparms.b^.u;
r_p1[1] := aliastriangleparms.b^.v;
r_p1[2] := aliastriangleparms.b^.s;
r_p1[3] := aliastriangleparms.b^.t;
r_p1[4] := aliastriangleparms.b^.l;
r_p1[5] := aliastriangleparms.b^.zi;
r_p2[0] := aliastriangleparms.c^.u;
r_p2[1] := aliastriangleparms.c^.v;
r_p2[2] := aliastriangleparms.c^.s;
r_p2[3] := aliastriangleparms.c^.t;
r_p2[4] := aliastriangleparms.c^.l;
r_p2[5] := aliastriangleparms.c^.zi;
R_PolysetSetEdgeTable;
R_RasterizeAliasPolySmooth;
end;
end;
(*
===================
R_PolysetScanLeftEdge_C
====================
*)
procedure R_PolysetScanLeftEdge_C(height: Integer);
begin
repeat
d_pedgespanpackage^.pdest := d_pdest;
d_pedgespanpackage^.pz := d_pz;
d_pedgespanpackage^.count := d_aspancount;
d_pedgespanpackage^.ptex := d_ptex;
d_pedgespanpackage^.sfrac := d_sfrac;
d_pedgespanpackage^.tfrac := d_tfrac;
// FIXME: need to clamp l, s, t, at both ends?
d_pedgespanpackage^.light := d_light;
d_pedgespanpackage^.zi := d_zi;
inc(Integer(d_pedgespanpackage), SizeOf(spanpackage_t));
inc(errorterm, erroradjustup);
if (errorterm >= 0) then
begin
inc(Integer(d_pdest), d_pdestextrastep);
inc(Integer(d_pz), (d_pzextrastep * SizeOf(SmallInt)));
inc(d_aspancount, d_countextrastep);
inc(Integer(d_ptex), d_ptexextrastep);
inc(d_sfrac, d_sfracextrastep);
inc(Integer(d_ptex), _SAR(d_sfrac, 16));
// inc(Integer(d_ptex), d_sfrac shr 16);
d_sfrac := d_sfrac and $FFFF;
inc(d_tfrac, d_tfracextrastep);
if (d_tfrac and $10000) <> 0 then
begin
inc(d_ptex, r_affinetridesc.skinwidth);
d_tfrac := d_tfrac and $FFFF;
end;
inc(d_light, d_lightextrastep);
inc(d_zi, d_ziextrastep);
dec(errorterm, erroradjustdown);
end
else
begin
inc(Integer(d_pdest), d_pdestbasestep);
inc(Integer(d_pz), d_pzbasestep*SizeOf(SmallInt));
inc(d_aspancount, ubasestep);
inc(Integer(d_ptex), d_ptexbasestep);
inc(d_sfrac, d_sfracbasestep);
inc(Integer(d_ptex), _SAR(d_sfrac, 16));
d_sfrac := d_sfrac and $FFFF;
inc(d_tfrac, d_tfracbasestep);
if (d_tfrac and $10000) <> 0 then
begin
inc(Integer(d_ptex), r_affinetridesc.skinwidth);
d_tfrac := d_tfrac and $FFFF;
end;
inc(d_light, d_lightbasestep);
inc(d_zi, d_zibasestep);
end;
dec(height);
until (height = 0);
end;
(*
===================
FloorDivMod
Returns mathematically correct (floor-based) quotient and remainder for
numer and denom, both of which should contain no fractional part. The
quotient must fit in 32 bits.
FIXME: GET RID OF THIS! (FloorDivMod)
====================
*)
procedure FloorDivMod(numer, denom: Single; quotient, rem: PInteger);
var
q: Integer;
r: Integer;
x: Single;
begin
if (numer >= 0.0) then
begin
x := floor(numer / denom);
q := Trunc(x);
r := Trunc(floor(numer - (x * denom)));
end
else
begin
//
// perform operations with positive values, and fix mod to make floor-based
//
x := floor(-numer / denom);
q := -Trunc(x);
r := Trunc(floor(-numer - (x * denom)));
if (r <> 0) then
begin
dec(q);
r := Trunc(denom - r);
end;
end;
quotient^ := q;
rem^ := r;
end;
(*
===================
R_PolysetSetUpForLineScan
====================
*)
procedure R_PolysetSetUpForLineScan(startvertu, startvertv, endvertu, endvertv: fixed8_t);
var
dm, dn: Single;
tm, tn: Integer;
ptemp: adivtab_p;
begin
// TODO: implement x86 version
errorterm := -1;
tm := endvertu - startvertu;
tn := endvertv - startvertv;
if (((tm <= 16) and (tm >= -15)) and ((tn <= 16) and (tn >= -15))) then
begin
ptemp := @adivtab[_SAL((tm + 15), 5) + (tn + 15)];
ubasestep := ptemp^.quotient;
erroradjustup := ptemp^.remainder;
erroradjustdown := tn;
end
else
begin
dm := tm;
dn := tn;
FloorDivMod(dm, dn, @ubasestep, @erroradjustup);
erroradjustdown := Trunc(dn);
end;
end;
(*
================
R_PolysetCalcGradients
================
*)
//#if id386 && !defined __linux__
{$IFDEF id386}
var
xstepdenominv: Single;
ystepdenominv: Single;
t0: Single;
t1: Single;
p01_minus_p21: Single;
p11_minus_p21: Single;
p00_minus_p20: Single;
p10_minus_p20: Single;
t0_int, t1_int: LongInt;
fpu_sp24_ceil_cw: LongInt external;
fpu_ceil_cw: LongInt external;
fpu_chop_cw: LongInt external;
const
one : Single = 1.0;
negative_one : Single = -1.0F;
procedure R_PolysetCalcGradients(skinwidth: Integer);
begin
(*
p00_minus_p20 = r_p0[0] - r_p2[0];
p01_minus_p21 = r_p0[1] - r_p2[1];
p10_minus_p20 = r_p1[0] - r_p2[0];
p11_minus_p21 = r_p1[1] - r_p2[1];
*)
asm
mov eax, dword ptr [r_p0+0]
mov ebx, dword ptr [r_p0+4]
sub eax, dword ptr [r_p2+0]
sub ebx, dword ptr [r_p2+4]
mov p00_minus_p20, eax
mov p01_minus_p21, ebx
fild dword ptr p00_minus_p20
fild dword ptr p01_minus_p21
mov eax, dword ptr [r_p1+0]
mov ebx, dword ptr [r_p1+4]
sub eax, dword ptr [r_p2+0]
sub ebx, dword ptr [r_p2+4]
fstp p01_minus_p21
fstp p00_minus_p20
mov p10_minus_p20, eax
mov p11_minus_p21, ebx
fild dword ptr p10_minus_p20
fild dword ptr p11_minus_p21
fstp p11_minus_p21
fstp p10_minus_p20
end;
(*
xstepdenominv = 1.0 / (float)d_xdenom;
ystepdenominv = -xstepdenominv;
*)
(*
** put FPU in single precision ceil mode
*)
asm
fldcw word ptr [fpu_sp24_ceil_cw]
// __asm fldcw word ptr [fpu_ceil_cw]
fild dword ptr d_xdenom //; d_xdenom
fdivr one //; 1 / d_xdenom
fst xstepdenominv //;
fmul negative_one //; -( 1 / d_xdenom )
// ceil () for light so positive steps are exaggerated, negative steps
// diminished, pushing us away from underflow toward overflow. Underflow is
// very visible, overflow is very unlikely, because of ambient lighting
(*
t0 = r_p0[4] - r_p2[4];
t1 = r_p1[4] - r_p2[4];
r_lstepx = (int)
ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
r_lstepy = (int)
ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
*)
mov eax, dword ptr [r_p0+16]
mov ebx, dword ptr [r_p1+16]
sub eax, dword ptr [r_p2+16]
sub ebx, dword ptr [r_p2+16]
fstp ystepdenominv //; (empty)
mov t0_int, eax
mov t1_int, ebx
fild t0_int //; t0
fild t1_int //; t1 | t0
fxch st(1) //; t0 | t1
fstp t0 //; t1
fst t1 //; t1
fmul p01_minus_p21 //; t1 * p01_minus_p21
fld t0 //; t0 | t1 * p01_minus_p21
fmul p11_minus_p21 //; t0 * p11_minus_p21 | t1 * p01_minus_p21
fld t1 //; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fmul p00_minus_p20 //; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fld t0 //; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fmul p10_minus_p20 //; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fxch st(2) //; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
fsubp st(3), st //; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
fsubrp st(1), st //; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
fxch st(1) //; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
fmul xstepdenominv //; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
fxch st(1)
fmul ystepdenominv //; r_lstepy | r_lstepx
fxch st(1) //; r_lstepx | r_lstepy
fistp dword ptr [r_lstepx]
fistp dword ptr [r_lstepy]
(*
** put FPU back into extended precision chop mode
*)
fldcw word ptr [fpu_chop_cw]
(*
t0 = r_p0[2] - r_p2[2];
t1 = r_p1[2] - r_p2[2];
r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
xstepdenominv);
r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
ystepdenominv);
*)
mov eax, dword ptr [r_p0+8]
mov ebx, dword ptr [r_p1+8]
sub eax, dword ptr [r_p2+8]
sub ebx, dword ptr [r_p2+8]
mov t0_int, eax
mov t1_int, ebx
fild t0_int //; t0
fild t1_int //; t1 | t0
fxch st(1) //; t0 | t1
fstp t0 //; t1
fst t1 //; (empty)
fmul p01_minus_p21 //; t1 * p01_minus_p21
fld t0 //; t0 | t1 * p01_minus_p21
fmul p11_minus_p21 //; t0 * p11_minus_p21 | t1 * p01_minus_p21
fld t1 //; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fmul p00_minus_p20 //; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fld t0 //; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fmul p10_minus_p20 //; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fxch st(2) //; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
fsubp st(3), st //; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
fsubrp st(1), st // ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
fxch st(1) //; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
fmul xstepdenominv //; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
fxch st(1)
fmul ystepdenominv //; r_lstepy | r_lstepx
fxch st(1) //; r_lstepx | r_lstepy
fistp dword ptr [r_sstepx]
fistp dword ptr [r_sstepy]
(*
t0 = r_p0[3] - r_p2[3];
t1 = r_p1[3] - r_p2[3];
r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
xstepdenominv);
r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
ystepdenominv);
*)
mov eax, dword ptr [r_p0+12]
mov ebx, dword ptr [r_p1+12]
sub eax, dword ptr [r_p2+12]
sub ebx, dword ptr [r_p2+12]
mov t0_int, eax
mov t1_int, ebx
fild t0_int //; t0
fild t1_int //; t1 | t0
fxch st(1) //; t0 | t1
fstp t0 //; t1
fst t1 //; (empty)
fmul p01_minus_p21 //; t1 * p01_minus_p21
fld t0 //; t0 | t1 * p01_minus_p21
fmul p11_minus_p21 //; t0 * p11_minus_p21 | t1 * p01_minus_p21
fld t1 //; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fmul p00_minus_p20 //; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fld t0 //; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fmul p10_minus_p20 //; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fxch st(2) //; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
fsubp st(3), st //; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
fsubrp st(1), st // ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
fxch st(1) //; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
fmul xstepdenominv //; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
fxch st(1)
fmul ystepdenominv //; r_lstepy | r_lstepx
fxch st(1) //; r_lstepx | r_lstepy
fistp dword ptr [r_tstepx]
fistp dword ptr [r_tstepy]
(*
t0 = r_p0[5] - r_p2[5];
t1 = r_p1[5] - r_p2[5];
r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
xstepdenominv);
r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
ystepdenominv);
*)
mov eax, dword ptr [r_p0+20]
mov ebx, dword ptr [r_p1+20]
sub eax, dword ptr [r_p2+20]
sub ebx, dword ptr [r_p2+20]
mov t0_int, eax
mov t1_int, ebx
fild t0_int //; t0
fild t1_int //; t1 | t0
fxch st(1) //; t0 | t1
fstp t0 //; t1
fst t1 //; (empty)
fmul p01_minus_p21 //; t1 * p01_minus_p21
fld t0 //; t0 | t1 * p01_minus_p21
fmul p11_minus_p21 //; t0 * p11_minus_p21 | t1 * p01_minus_p21
fld t1 //; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fmul p00_minus_p20 //; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fld t0 //; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fmul p10_minus_p20 //; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
fxch st(2) //; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
fsubp st(3), st //; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
fsubrp st(1), st // ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
fxch st(1) //; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
fmul xstepdenominv //; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
fxch st(1)
fmul ystepdenominv //; r_lstepy | r_lstepx
fxch st(1) //; r_lstepx | r_lstepy
fistp dword ptr [r_zistepx]
fistp dword ptr [r_zistepy]
(*
#if id386ALIAS
a_sstepxfrac = r_sstepx << 16;
a_tstepxfrac = r_tstepx << 16;
#else
a_sstepxfrac = r_sstepx & 0xFFFF;
a_tstepxfrac = r_tstepx & 0xFFFF;
#endif
*)
mov eax, d_pdrawspans
cmp eax, offset R_PolysetDrawSpans8_Opaque
mov eax, r_sstepx
mov ebx, r_tstepx
jne @translucent
//#if id386ALIAS
shl eax, 16
shl ebx, 16
jmp @done_with_steps
//#else
@translucent:
and eax, 0ffffh
and ebx, 0ffffh
//#endif
@done_with_steps:
mov a_sstepxfrac, eax
mov a_tstepxfrac, ebx
(*
a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
*)
mov ebx, r_tstepx
mov ecx, r_sstepx
sar ebx, 16
mov eax, skinwidth
mul ebx
sar ecx, 16
add eax, ecx
mov a_ststepxwhole, eax
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -