📄 r_drawa.pas
字号:
// }
LSideDone:
// edge->u_step = u_step*0x100000;
// edge->u = u*0x100000 + 0xFFFFF;
fmul ds:dword ptr[fp_1m] // u*0x100000 | ustep
fxch st(1) // ustep | u*0x100000
fmul ds:dword ptr[fp_1m] // ustep*0x100000 | u*0x100000
fxch st(1) // u*0x100000 | ustep*0x100000
fadd ds:dword ptr[fp_1m_minus_1] // u*0x100000 + 0xFFFFF | ustep*0x100000
fxch st(1) // ustep*0x100000 | u*0x100000 + 0xFFFFF
fistp ds:dword ptr[et_u_step+edi] // u*0x100000 + 0xFFFFF
fistp ds:dword ptr[et_u+edi]
// // we need to do this to avoid stepping off the edges if a very nearly
// // horizontal edge is less than epsilon above a scan, and numeric error
// // causes it to incorrectly extend to the scan, and the extension of the
// // line goes off the edge of the screen
// // FIXME: is this actually needed?
// if (edge->u < r_refdef.vrect_x_adj_shift20)
// edge->u = r_refdef.vrect_x_adj_shift20;
// if (edge->u > r_refdef.vrectright_adj_shift20)
// edge->u = r_refdef.vrectright_adj_shift20;
mov eax,ds:dword ptr[et_u+edi]
mov edx,ds:dword ptr[r_refdef+rd_vrect_x_adj_shift20]
cmp eax,edx
jl LP4
mov edx,ds:dword ptr[r_refdef+rd_vrectright_adj_shift20]
cmp eax,edx
jng LP5
LP4:
mov ds:dword ptr[et_u+edi],edx
mov eax,edx
LP5:
// // sort the edge in normally
// u_check = edge->u;
//
// if (edge->surfs[0])
// u_check++; // sort trailers after leaders
add eax,esi
// if (!newedges[v] || newedges[v]->u >= u_check)
// {
mov esi,ds:dword ptr[newedges+ebx*4]
test esi,esi
jz LDoFirst
cmp ds:dword ptr[et_u+esi],eax
jl LNotFirst
LDoFirst:
// edge->next = newedges[v];
// newedges[v] = edge;
mov ds:dword ptr[et_next+edi],esi
mov ds:dword ptr[newedges+ebx*4],edi
jmp LSetRemove
// }
LNotFirst:
// else
// {
// pcheck = newedges[v];
//
// while (pcheck->next && pcheck->next->u < u_check)
// pcheck = pcheck->next;
LFindInsertLoop:
mov edx,esi
mov esi,ds:dword ptr[et_next+esi]
test esi,esi
jz LInsertFound
cmp ds:dword ptr[et_u+esi],eax
jl LFindInsertLoop
LInsertFound:
// edge->next = pcheck->next;
// pcheck->next = edge;
mov ds:dword ptr[et_next+edi],esi
mov ds:dword ptr[et_next+edx],edi
// }
LSetRemove:
// edge->nextremove = removeedges[v2];
// removeedges[v2] = edge;
mov eax,ds:dword ptr[removeedges+ecx*4]
mov ds:dword ptr[removeedges+ecx*4],edi
mov ds:dword ptr[et_nextremove+edi],eax
Ldone:
mov esp,ds:dword ptr[Lstack] // clear temporary variables from stack
pop ebx // restore register variables
pop edi
pop esi
ret
// at least one point is clipped
Lp2_:
test eax,eax
jns Lp1_
// else
// {
// // point 0 is clipped
// if (d1 < 0)
// {
mov eax,ds:dword ptr[Ld1]
test eax,eax
jns Lp3_
// // both points are clipped
// // we do cache fully clipped edges
// if (!leftclipped)
mov eax,ds:dword ptr[r_leftclipped]
mov ecx,ds:dword ptr[r_pedge]
test eax,eax
jnz Ldone
// r_pedge->framecount = r_framecount;
mov eax,ds:dword ptr[r_framecount]
and eax,offset FRAMECOUNT_MASK
or eax,offset FULLY_CLIPPED_CACHED
mov ds:dword ptr[cacheoffset],eax
// return;
jmp Ldone
// }
Lp1_:
// // point 0 is unclipped
// if (d1 >= 0)
// {
// // both points are unclipped
// continue;
// // only point 1 is clipped
// f = d0 / (d0 - d1);
fld ds:dword ptr[Ld0]
fld ds:dword ptr[Ld1]
fsubr st(0),st(1)
// // we don't cache partially clipped edges
mov ds:dword ptr[cacheoffset],07FFFFFFFh
fdivp st(1),st(0)
sub esp,offset mv_size // allocate space for clipvert
// clipvert.position[0] = pv0->position[0] +
// f * (pv1->position[0] - pv0->position[0]);
// clipvert.position[1] = pv0->position[1] +
// f * (pv1->position[1] - pv0->position[1]);
// clipvert.position[2] = pv0->position[2] +
// f * (pv1->position[2] - pv0->position[2]);
fld ds:dword ptr[mv_position+8+edx]
fsub ds:dword ptr[mv_position+8+esi]
fld ds:dword ptr[mv_position+4+edx]
fsub ds:dword ptr[mv_position+4+esi]
fld ds:dword ptr[mv_position+0+edx]
fsub ds:dword ptr[mv_position+0+esi] // 0 | 1 | 2
// replace pv1 with the clip point
mov edx,esp
mov eax,ds:dword ptr[cp_leftedge+ebx]
test al,al
fmul st(0),st(3)
fxch st(1) // 1 | 0 | 2
fmul st(0),st(3)
fxch st(2) // 2 | 0 | 1
fmulp st(3),st(0) // 0 | 1 | 2
fadd ds:dword ptr[mv_position+0+esi]
fxch st(1) // 1 | 0 | 2
fadd ds:dword ptr[mv_position+4+esi]
fxch st(2) // 2 | 0 | 1
fadd ds:dword ptr[mv_position+8+esi]
fxch st(1) // 0 | 2 | 1
fstp ds:dword ptr[mv_position+0+esp] // 2 | 1
fstp ds:dword ptr[mv_position+8+esp] // 1
fstp ds:dword ptr[mv_position+4+esp]
// if (clip->leftedge)
// {
jz Ltestright
// r_leftclipped = true;
// r_leftexit = clipvert;
mov ds:dword ptr[r_leftclipped],1
mov eax,ds:dword ptr[mv_position+0+esp]
mov ds:dword ptr[r_leftexit+mv_position+0],eax
mov eax,ds:dword ptr[mv_position+4+esp]
mov ds:dword ptr[r_leftexit+mv_position+4],eax
mov eax,ds:dword ptr[mv_position+8+esp]
mov ds:dword ptr[r_leftexit+mv_position+8],eax
jmp Lcontinue
// }
Ltestright:
// else if (clip->rightedge)
// {
test ah,ah
jz Lcontinue
// r_rightclipped = true;
// r_rightexit = clipvert;
mov ds:dword ptr[r_rightclipped],1
mov eax,ds:dword ptr[mv_position+0+esp]
mov ds:dword ptr[r_rightexit+mv_position+0],eax
mov eax,ds:dword ptr[mv_position+4+esp]
mov ds:dword ptr[r_rightexit+mv_position+4],eax
mov eax,ds:dword ptr[mv_position+8+esp]
mov ds:dword ptr[r_rightexit+mv_position+8],eax
// }
//
// R_ClipEdge (pv0, &clipvert, clip->next);
// return;
// }
jmp Lcontinue
// }
Lp3_:
// // only point 0 is clipped
// r_lastvertvalid = false;
mov ds:dword ptr[r_lastvertvalid],0
// f = d0 / (d0 - d1);
fld ds:dword ptr[Ld0]
fld ds:dword ptr[Ld1]
fsubr st(0),st(1)
// // we don't cache partially clipped edges
mov ds:dword ptr[cacheoffset],07FFFFFFFh
fdivp st(1),st(0)
sub esp,offset mv_size // allocate space for clipvert
// clipvert.position[0] = pv0->position[0] +
// f * (pv1->position[0] - pv0->position[0]);
// clipvert.position[1] = pv0->position[1] +
// f * (pv1->position[1] - pv0->position[1]);
// clipvert.position[2] = pv0->position[2] +
// f * (pv1->position[2] - pv0->position[2]);
fld ds:dword ptr[mv_position+8+edx]
fsub ds:dword ptr[mv_position+8+esi]
fld ds:dword ptr[mv_position+4+edx]
fsub ds:dword ptr[mv_position+4+esi]
fld ds:dword ptr[mv_position+0+edx]
fsub ds:dword ptr[mv_position+0+esi] // 0 | 1 | 2
mov eax,ds:dword ptr[cp_leftedge+ebx]
test al,al
fmul st(0),st(3)
fxch st(1) // 1 | 0 | 2
fmul st(0),st(3)
fxch st(2) // 2 | 0 | 1
fmulp st(3),st(0) // 0 | 1 | 2
fadd ds:dword ptr[mv_position+0+esi]
fxch st(1) // 1 | 0 | 2
fadd ds:dword ptr[mv_position+4+esi]
fxch st(2) // 2 | 0 | 1
fadd ds:dword ptr[mv_position+8+esi]
fxch st(1) // 0 | 2 | 1
fstp ds:dword ptr[mv_position+0+esp] // 2 | 1
fstp ds:dword ptr[mv_position+8+esp] // 1
fstp ds:dword ptr[mv_position+4+esp]
// replace pv0 with the clip point
mov esi,esp
// if (clip->leftedge)
// {
jz Ltestright2
// r_leftclipped = true;
// r_leftenter = clipvert;
mov ds:dword ptr[r_leftclipped],1
mov eax,ds:dword ptr[mv_position+0+esp]
mov ds:dword ptr[r_leftenter+mv_position+0],eax
mov eax,ds:dword ptr[mv_position+4+esp]
mov ds:dword ptr[r_leftenter+mv_position+4],eax
mov eax,ds:dword ptr[mv_position+8+esp]
mov ds:dword ptr[r_leftenter+mv_position+8],eax
jmp Lcontinue
// }
Ltestright2:
// else if (clip->rightedge)
// {
test ah,ah
jz Lcontinue
// r_rightclipped = true;
// r_rightenter = clipvert;
mov ds:dword ptr[r_rightclipped],1
mov eax,ds:dword ptr[mv_position+0+esp]
mov ds:dword ptr[r_rightenter+mv_position+0],eax
mov eax,ds:dword ptr[mv_position+4+esp]
mov ds:dword ptr[r_rightenter+mv_position+4],eax
mov eax,ds:dword ptr[mv_position+8+esp]
mov ds:dword ptr[r_rightenter+mv_position+8],eax
// }
jmp Lcontinue
// %esi = vec3_t point to transform and project
// %edx preserved
LTransformAndProject:
// // transform and project
// VectorSubtract (world, modelorg, local);
fld ds:dword ptr[mv_position+0+esi]
fsub ds:dword ptr[modelorg+0]
fld ds:dword ptr[mv_position+4+esi]
fsub ds:dword ptr[modelorg+4]
fld ds:dword ptr[mv_position+8+esi]
fsub ds:dword ptr[modelorg+8]
fxch st(2) // local[0] | local[1] | local[2]
// TransformVector (local, transformed);
//
// if (transformed[2] < NEAR_CLIP)
// transformed[2] = NEAR_CLIP;
//
// lzi0 = 1.0 / transformed[2];
fld st(0) // local[0] | local[0] | local[1] | local[2]
fmul ds:dword ptr[vpn+0] // zm0 | local[0] | local[1] | local[2]
fld st(1) // local[0] | zm0 | local[0] | local[1] |
// local[2]
fmul ds:dword ptr[vright+0] // xm0 | zm0 | local[0] | local[1] | local[2]
fxch st(2) // local[0] | zm0 | xm0 | local[1] | local[2]
fmul ds:dword ptr[vup+0] // ym0 | zm0 | xm0 | local[1] | local[2]
fld st(3) // local[1] | ym0 | zm0 | xm0 | local[1] |
// local[2]
fmul ds:dword ptr[vpn+4] // zm1 | ym0 | zm0 | xm0 | local[1] |
// local[2]
fld st(4) // local[1] | zm1 | ym0 | zm0 | xm0 |
// local[1] | local[2]
fmul ds:dword ptr[vright+4] // xm1 | zm1 | ym0 | zm0 | xm0 |
// local[1] | local[2]
fxch st(5) // local[1] | zm1 | ym0 | zm0 | xm0 |
// xm1 | local[2]
fmul ds:dword ptr[vup+4] // ym1 | zm1 | ym0 | zm0 | xm0 |
// xm1 | local[2]
fxch st(1) // zm1 | ym1 | ym0 | zm0 | xm0 |
// xm1 | local[2]
faddp st(3),st(0) // ym1 | ym0 | zm2 | xm0 | xm1 | local[2]
fxch st(3) // xm0 | ym0 | zm2 | ym1 | xm1 | local[2]
faddp st(4),st(0) // ym0 | zm2 | ym1 | xm2 | local[2]
faddp st(2),st(0) // zm2 | ym2 | xm2 | local[2]
fld st(3) // local[2] | zm2 | ym2 | xm2 | local[2]
fmul ds:dword ptr[vpn+8] // zm3 | zm2 | ym2 | xm2 | local[2]
fld st(4) // local[2] | zm3 | zm2 | ym2 | xm2 | local[2]
fmul ds:dword ptr[vright+8] // xm3 | zm3 | zm2 | ym2 | xm2 | local[2]
fxch st(5) // local[2] | zm3 | zm2 | ym2 | xm2 | xm3
fmul ds:dword ptr[vup+8] // ym3 | zm3 | zm2 | ym2 | xm2 | xm3
fxch st(1) // zm3 | ym3 | zm2 | ym2 | xm2 | xm3
faddp st(2),st(0) // ym3 | zm4 | ym2 | xm2 | xm3
fxch st(4) // xm3 | zm4 | ym2 | xm2 | ym3
faddp st(3),st(0) // zm4 | ym2 | xm4 | ym3
fxch st(1) // ym2 | zm4 | xm4 | ym3
faddp st(3),st(0) // zm4 | xm4 | ym4
fcom ds:dword ptr[Lfp_near_clip]
fnstsw ax
test ah,1
jz LNoClip
fstp st(0)
fld ds:dword ptr[Lfp_near_clip]
LNoClip:
fdivr ds:dword ptr[float_1] // lzi0 | x | y
fxch st(1) // x | lzi0 | y
// // FIXME: build x/yscale into transform?
// scale = xscale * lzi0;
// u0 = (xcenter + scale*transformed[0]);
fld ds:dword ptr[xscale] // xscale | x | lzi0 | y
fmul st(0),st(2) // scale | x | lzi0 | y
fmulp st(1),st(0) // scale*x | lzi0 | y
fadd ds:dword ptr[xcenter] // u0 | lzi0 | y
// if (u0 < r_refdef.fvrectx_adj)
// u0 = r_refdef.fvrectx_adj;
// if (u0 > r_refdef.fvrectright_adj)
// u0 = r_refdef.fvrectright_adj;
// FIXME: use integer compares of floats?
fcom ds:dword ptr[r_refdef+rd_fvrectx_adj]
fnstsw ax
test ah,1
jz LClampP0
fstp st(0)
fld ds:dword ptr[r_refdef+rd_fvrectx_adj]
LClampP0:
fcom ds:dword ptr[r_refdef+rd_fvrectright_adj]
fnstsw ax
test ah,045h
jnz LClampP1
fstp st(0)
fld ds:dword ptr[r_refdef+rd_fvrectright_adj]
LClampP1:
fld st(1) // lzi0 | u0 | lzi0 | y
// scale = yscale * lzi0;
// v0 = (ycenter - scale*transformed[1]);
fmul ds:dword ptr[yscale] // scale | u0 | lzi0 | y
fmulp st(3),st(0) // u0 | lzi0 | scale*y
fxch st(2) // scale*y | lzi0 | u0
fsubr ds:dword ptr[ycenter] // v0 | lzi0 | u0
// if (v0 < r_refdef.fvrecty_adj)
// v0 = r_refdef.fvrecty_adj;
// if (v0 > r_refdef.fvrectbottom_adj)
// v0 = r_refdef.fvrectbottom_adj;
// FIXME: use integer compares of floats?
fcom ds:dword ptr[r_refdef+rd_fvrecty_adj]
fnstsw ax
test ah,1
jz LClampP2
fstp st(0)
fld ds:dword ptr[r_refdef+rd_fvrecty_adj]
LClampP2:
fcom ds:dword ptr[r_refdef+rd_fvrectbottom_adj]
fnstsw ax
test ah,045h
jnz LClampP3
fstp st(0)
fld ds:dword ptr[r_refdef+rd_fvrectbottom_adj]
LClampP3:
ret
end;
{$ENDIF}
initialization
Sys_SetFPCW;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -