📄 r_edgea.pas
字号:
@Lgs_edgeloop:
mov edi,ds:dword ptr[et_surfs+ebx]
mov eax,ds:dword ptr[surfaces]
mov esi,edi
and edi,0FFFF0000h
and esi,0FFFFh
jz @Lgs_leading // not a trailing edge
// it has a left surface, so a surface is going away for this span
shl esi,offset SURF_T_SHIFT
add esi,eax
test edi,edi
jz @Lgs_trailing
// both leading and trailing
call @TrailingEdge
mov eax,ds:dword ptr[surfaces]
// ---------------------------------------------------------------
// handle a leading edge
// ---------------------------------------------------------------
@Lgs_leading:
shr edi,16-SURF_T_SHIFT
mov eax,ds:dword ptr[surfaces]
add edi,eax
// mov esi,ds:dword ptr[12345678h] // surf2 = surfaces[1].next;
mov esi,ds:dword ptr[LPatch2_Value] // surf2 = surfaces[1].next;
@LPatch2:
mov edx,ds:dword ptr[st_spanstate+edi]
mov eax,ds:dword ptr[st_insubmodel+edi]
test eax,eax
jnz @Lbmodel_leading
// handle a leading non-bmodel edge
// 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)
test edx,edx
jnz @Lxl_done
// if (surf->key < surf2->key)
// goto newtop;
inc edx
mov eax,ds:dword ptr[st_key+edi]
mov ds:dword ptr[st_spanstate+edi],edx
mov ecx,ds:dword ptr[st_key+esi]
cmp eax,ecx
jl @Lnewtop
// main sorting loop to search through surface stack until insertion point
// found. Always terminates because background surface is sentinel
// do
// {
// surf2 = surf2->next;
// } while (surf->key >= surf2->key);
@Lsortloopnb:
mov esi,ds:dword ptr[st_next+esi]
mov ecx,ds:dword ptr[st_key+esi]
cmp eax,ecx
jge @Lsortloopnb
jmp @LInsertAndExit
// handle a leading bmodel edge
{$align 4}
@Lbmodel_leading:
// 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)
test edx,edx
jnz @Lxl_done
mov ecx,ds:dword ptr[_r_bmodelactive]
inc edx
inc ecx
mov ds:dword ptr[st_spanstate+edi],edx
mov ds:dword ptr[_r_bmodelactive],ecx
// if (surf->key < surf2->key)
// goto newtop;
mov eax,ds:dword ptr[st_key+edi]
mov ecx,ds:dword ptr[st_key+esi]
cmp eax,ecx
jl @Lnewtop
// if ((surf->key == surf2->key) && surf->insubmodel)
// {
jz @Lzcheck_for_newtop
// main sorting loop to search through surface stack until insertion point
// found. Always terminates because background surface is sentinel
// do
// {
// surf2 = surf2->next;
// } while (surf->key > surf2->key);
@Lsortloop:
mov esi,ds:dword ptr[st_next+esi]
mov ecx,ds:dword ptr[st_key+esi]
cmp eax,ecx
jg @Lsortloop
jne @LInsertAndExit
// Do 1/z sorting to see if we've arrived in the right position
mov eax,ds:dword ptr[et_u+ebx]
sub eax,0FFFFFh
mov ds:dword ptr[Ltemp],eax
fild ds:dword ptr[Ltemp]
fmul ds:dword ptr[float_1_div_0100000h] // fu = (float)(edge->u - 0xFFFFF) *
// (1.0 / 0x100000);
fld st(0) // fu | fu
fmul ds:dword ptr[st_d_zistepu+edi] // fu*surf->d_zistepu | fu
fld ds:dword ptr[fv] // fv | fu*surf->d_zistepu | fu
fmul ds:dword ptr[st_d_zistepv+edi] // fv*surf->d_zistepv | fu*surf->d_zistepu | fu
fxch st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu
fadd ds:dword ptr[st_d_ziorigin+edi] // fu*surf->d_zistepu + surf->d_ziorigin |
// fv*surf->d_zistepv | fu
fld ds:dword ptr[st_d_zistepu+esi] // surf2->d_zistepu |
// fu*surf->d_zistepu + surf->d_ziorigin |
// fv*surf->d_zistepv | fu
fmul st(0),st(3) // fu*surf2->d_zistepu |
// fu*surf->d_zistepu + surf->d_ziorigin |
// fv*surf->d_zistepv | fu
fxch st(1) // fu*surf->d_zistepu + surf->d_ziorigin |
// fu*surf2->d_zistepu |
// fv*surf->d_zistepv | fu
faddp st(2),st(0) // fu*surf2->d_zistepu | newzi | fu
fld ds:dword ptr[fv] // fv | fu*surf2->d_zistepu | newzi | fu
fmul ds:dword ptr[st_d_zistepv+esi] // fv*surf2->d_zistepv |
// fu*surf2->d_zistepu | newzi | fu
fld st(2) // newzi | fv*surf2->d_zistepv |
// fu*surf2->d_zistepu | newzi | fu
fmul ds:dword ptr[float_point_999] // newzibottom | fv*surf2->d_zistepv |
// fu*surf2->d_zistepu | newzi | fu
fxch st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv |
// newzibottom | newzi | fu
fadd ds:dword ptr[st_d_ziorigin+esi] // fu*surf2->d_zistepu + surf2->d_ziorigin |
// fv*surf2->d_zistepv | newzibottom | newzi |
// fu
faddp st(1),st(0) // testzi | newzibottom | newzi | fu
fxch st(1) // newzibottom | testzi | newzi | fu
// if (newzibottom >= testzi)
// goto Lgotposition;
fcomp st(1) // testzi | newzi | fu
fxch st(1) // newzi | testzi | fu
fmul ds:dword ptr[float_1_point_001] // newzitop | testzi | fu
fxch st(1) // testzi | newzitop | fu
fnstsw ax
test ah,001h
jz @Lgotposition_fpop3
// if (newzitop >= testzi)
// {
fcomp st(1) // newzitop | fu
fnstsw ax
test ah,045h
jz @Lsortloop_fpop2
// if (surf->d_zistepu >= surf2->d_zistepu)
// goto newtop;
fld ds:dword ptr[st_d_zistepu+edi] // surf->d_zistepu | newzitop| fu
fcomp ds:dword ptr[st_d_zistepu+esi] // newzitop | fu
fnstsw ax
test ah,001h
jz @Lgotposition_fpop2
fstp st(0) // clear the FPstack
fstp st(0)
mov eax,ds:dword ptr[st_key+edi]
jmp @Lsortloop
@Lgotposition_fpop3:
fstp st(0)
@Lgotposition_fpop2:
fstp st(0)
fstp st(0)
jmp @LInsertAndExit
// emit a span (obscures current top)
@Lnewtop_fpop3:
fstp st(0)
@Lnewtop_fpop2:
fstp st(0)
fstp st(0)
mov eax,ds:dword ptr[st_key+edi] // reload the sorting key
@Lnewtop:
mov eax,ds:dword ptr[et_u+ebx]
mov edx,ds:dword ptr[st_last_u+esi]
shr eax,20 // iu = integral pixel u
mov ds:dword ptr[st_last_u+edi],eax // surf->last_u = iu;
cmp eax,edx
jle @LInsertAndExit // iu <= surf->last_u, so nothing to emit
sub eax,edx
mov ds:dword ptr[espan_t_u+ebp],edx // span->u = surf->last_u;
mov ds:dword ptr[espan_t_count+ebp],eax // span->count = iu - span->u;
mov eax,ds:dword ptr[current_iv]
mov ds:dword ptr[espan_t_v+ebp],eax // span->v = current_iv;
mov eax,ds:dword ptr[st_spans+esi]
mov ds:dword ptr[espan_t_pnext+ebp],eax // span->pnext = surf->spans;
mov ds:dword ptr[st_spans+esi],ebp // surf->spans = span;
add ebp,offset espan_t_size
@LInsertAndExit:
// insert before surf2
mov ds:dword ptr[st_next+edi],esi // surf->next = surf2;
mov eax,ds:dword ptr[st_prev+esi]
mov ds:dword ptr[st_prev+edi],eax // surf->prev = surf2->prev;
mov ds:dword ptr[st_prev+esi],edi // surf2->prev = surf;
mov ds:dword ptr[st_next+eax],edi // surf2->prev->next = surf;
// ---------------------------------------------------------------
// leading edge done
// ---------------------------------------------------------------
// ---------------------------------------------------------------
// see if there are any more edges
// ---------------------------------------------------------------
@Lgs_nextedge:
mov ebx,ds:dword ptr[et_next+ebx]
cmp ebx,offset edge_tail
jnz @Lgs_edgeloop
// clean up at the right edge
@Lgs_lastspan:
// now that we've reached the right edge of the screen, we're done with any
// unfinished surfaces, so emit a span for whatever's on top
// mov esi,ds:dword ptr[12345678h] // surfaces[1].st_next
mov esi,ds:dword ptr[LPatch3_Value] // surfaces[1].st_next
@LPatch3:
mov eax,ds:dword ptr[edge_tail_u_shift20]
xor ecx,ecx
mov edx,ds:dword ptr[st_last_u+esi]
sub eax,edx
jle @Lgs_resetspanstate
mov ds:dword ptr[espan_t_u+ebp],edx
mov ds:dword ptr[espan_t_count+ebp],eax
mov eax,ds:dword ptr[current_iv]
mov ds:dword ptr[espan_t_v+ebp],eax
mov eax,ds:dword ptr[st_spans+esi]
mov ds:dword ptr[espan_t_pnext+ebp],eax
mov ds:dword ptr[st_spans+esi],ebp
add ebp,offset espan_t_size
// reset spanstate for all surfaces in the surface stack
@Lgs_resetspanstate:
mov ds:dword ptr[st_spanstate+esi],ecx
mov esi,ds:dword ptr[st_next+esi]
// cmp esi,012345678h // &surfaces[1]
cmp esi,ds:dword ptr[LPatch4_Value]
@LPatch4:
jnz @Lgs_resetspanstate
// store the final span_p
mov ds:dword ptr[span_p],ebp
pop ebx // restore register variables
pop esi
pop edi
pop ebp // restore the caller's stack frame
jmp @Exit_Func
// ---------------------------------------------------------------
// 1/z sorting for bmodels in the same leaf
// ---------------------------------------------------------------
{$align 4}
@Lxl_done:
inc edx
mov ds:dword ptr[st_spanstate+edi],edx
jmp @Lgs_nextedge
{$align 4}
@Lzcheck_for_newtop:
mov eax,ds:dword ptr[et_u+ebx]
sub eax,0FFFFFh
mov ds:dword ptr[Ltemp],eax
fild ds:dword ptr[Ltemp]
fmul ds:dword ptr[float_1_div_0100000h] // fu = (float)(edge->u - 0xFFFFF) *
// (1.0 / 0x100000)//
fld st(0) // fu | fu
fmul ds:dword ptr[st_d_zistepu+edi] // fu*surf->d_zistepu | fu
fld ds:dword ptr[fv] // fv | fu*surf->d_zistepu | fu
fmul ds:dword ptr[st_d_zistepv+edi] // fv*surf->d_zistepv | fu*surf->d_zistepu | fu
fxch st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu
fadd ds:dword ptr[st_d_ziorigin+edi] // fu*surf->d_zistepu + surf->d_ziorigin |
// fv*surf->d_zistepv | fu
fld ds:dword ptr[st_d_zistepu+esi] // surf2->d_zistepu |
// fu*surf->d_zistepu + surf->d_ziorigin |
// fv*surf->d_zistepv | fu
fmul st(0),st(3) // fu*surf2->d_zistepu |
// fu*surf->d_zistepu + surf->d_ziorigin |
// fv*surf->d_zistepv | fu
fxch st(1) // fu*surf->d_zistepu + surf->d_ziorigin |
// fu*surf2->d_zistepu |
// fv*surf->d_zistepv | fu
faddp st(2),st(0) // fu*surf2->d_zistepu | newzi | fu
fld ds:dword ptr[fv] // fv | fu*surf2->d_zistepu | newzi | fu
fmul ds:dword ptr[st_d_zistepv+esi] // fv*surf2->d_zistepv |
// fu*surf2->d_zistepu | newzi | fu
fld st(2) // newzi | fv*surf2->d_zistepv |
// fu*surf2->d_zistepu | newzi | fu
fmul ds:dword ptr[float_point_999] // newzibottom | fv*surf2->d_zistepv |
// fu*surf2->d_zistepu | newzi | fu
fxch st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv |
// newzibottom | newzi | fu
fadd ds:dword ptr[st_d_ziorigin+esi] // fu*surf2->d_zistepu + surf2->d_ziorigin |
// fv*surf2->d_zistepv | newzibottom | newzi |
// fu
faddp st(1),st(0) // testzi | newzibottom | newzi | fu
fxch st(1) // newzibottom | testzi | newzi | fu
// if (newzibottom >= testzi)
// goto newtop//
fcomp st(1) // testzi | newzi | fu
fxch st(1) // newzi | testzi | fu
fmul ds:dword ptr[float_1_point_001] // newzitop | testzi | fu
fxch st(1) // testzi | newzitop | fu
fnstsw ax
test ah,001h
jz @Lnewtop_fpop3
// if (newzitop >= testzi)
//
fcomp st(1) // newzitop | fu
fnstsw ax
test ah,045h
jz @Lsortloop_fpop2
// if (surf->d_zistepu >= surf2->d_zistepu)
// goto newtop//
fld ds:dword ptr[st_d_zistepu+edi] // surf->d_zistepu | newzitop | fu
fcomp ds:dword ptr[st_d_zistepu+esi] // newzitop | fu
fnstsw ax
test ah,001h
jz @Lnewtop_fpop2
@Lsortloop_fpop2:
fstp st(0) // clear the FP stack
fstp st(0)
mov eax,ds:dword ptr[st_key+edi]
jmp @Lsortloop
@Exit_Func:
end;
//----------------------------------------------------------------------
// Surface array address code patching routine
//----------------------------------------------------------------------
procedure R_SurfacePatch;
asm
{$align 4}
mov eax,ds:dword ptr[surfaces]
add eax,offset st_size
mov ds:dword ptr[LPatch4_Value-4],eax
add eax,offset st_next
mov ds:dword ptr[LPatch0_Value-4],eax
mov ds:dword ptr[LPatch2_Value-4],eax
mov ds:dword ptr[LPatch3_Value-4],eax
end;
{$ENDIF}
initialization
{$IFDEF id386}
Ltemp := 0;
float_1_div_0100000h := $035800000; //1.0/(float)0x100000
float_point_999 := 0.999;
float_1_point_001 := 1.001;
// these routines should not be called.
R_EdgeCodeStart := TEdgeCode(Addr(R_InsertNewEdges));
R_EdgeCodeEnd := TEdgeCode(Addr(R_SurfacePatch));
{$ENDIF}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -