📄 r_draw16.asm
字号:
sbb ecx,ecx
add ebx,ebp
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
jmp LEntry15_16
;----------------------------------------
Entry16_16:
add edx,eax
mov al,ds:byte ptr[esi]
sbb ecx,ecx
add ebx,ebp
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
sbb ecx,ecx
mov ds:byte ptr[1+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry15_16:
sbb ecx,ecx
mov ds:byte ptr[2+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry14_16:
sbb ecx,ecx
mov ds:byte ptr[3+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry13_16:
sbb ecx,ecx
mov ds:byte ptr[4+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry12_16:
sbb ecx,ecx
mov ds:byte ptr[5+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry11_16:
sbb ecx,ecx
mov ds:byte ptr[6+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry10_16:
sbb ecx,ecx
mov ds:byte ptr[7+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry9_16:
sbb ecx,ecx
mov ds:byte ptr[8+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry8_16:
sbb ecx,ecx
mov ds:byte ptr[9+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry7_16:
sbb ecx,ecx
mov ds:byte ptr[10+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry6_16:
sbb ecx,ecx
mov ds:byte ptr[11+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry5_16:
sbb ecx,ecx
mov ds:byte ptr[12+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
add edx,ds:dword ptr[tstep]
LEntry4_16:
sbb ecx,ecx
mov ds:byte ptr[13+edi],al
add ebx,ebp
mov al,ds:byte ptr[esi]
adc esi,ds:dword ptr[advancetable+4+ecx*4]
LEntry3_16:
mov ds:byte ptr[14+edi],al
mov al,ds:byte ptr[esi]
LEntry2_16:
LEndSpan:
;
; clear s/z, t/z, 1/z from FP stack
;
fstp st(0)
fstp st(0)
fstp st(0)
mov ebx,ds:dword ptr[pspantemp] ; restore spans pointer
mov ebx,ds:dword ptr[espan_t_pnext+ebx] ; point to next span
test ebx,ebx ; any more spans?
mov ds:byte ptr[15+edi],al
jnz LSpanLoop ; more spans
pop ebx ; restore register variables
pop esi
pop edi
pop ebp ; restore the caller's stack frame
ret
;----------------------------------------------------------------------
; 8-bpp horizontal span z drawing codefor polygons, with no transparency.
;
; Assumes there is at least one span in pzspans, and that every span
; contains at least one pixel
;----------------------------------------------------------------------
; z-clamp on a non-negative gradient span
LClamp:
mov edx,040000000h
xor ebx,ebx
fstp st(0)
jmp LZDraw
; z-clamp on a negative gradient span
LClampNeg:
mov edx,040000000h
xor ebx,ebx
fstp st(0)
jmp LZDrawNeg
pzspans equ 4+16
public _D_DrawZSpans
_D_DrawZSpans:
push ebp ; preserve caller's stack frame
push edi
push esi ; preserve register variables
push ebx
fld ds:dword ptr[_d_zistepu]
mov eax,ds:dword ptr[_d_zistepu]
mov esi,ds:dword ptr[pzspans+esp]
test eax,eax
jz LFNegSpan
fmul ds:dword ptr[Float2ToThe31nd]
fistp ds:dword ptr[izistep] ; note: we are relying on FP exceptions being turned
; off here to avoid range problems
mov ebx,ds:dword ptr[izistep] ; remains loaded for all spans
LFSpanLoop:
; set up the initial 1/z value
fild ds:dword ptr[espan_t_v+esi]
fild ds:dword ptr[espan_t_u+esi]
mov ecx,ds:dword ptr[espan_t_v+esi]
mov edi,ds:dword ptr[_d_pzbuffer]
fmul ds:dword ptr[_d_zistepu]
fxch st(1)
fmul ds:dword ptr[_d_zistepv]
fxch st(1)
fadd ds:dword ptr[_d_ziorigin]
imul ecx,ds:dword ptr[_d_zrowbytes]
faddp st(1),st(0)
; clamp if z is nearer than 2 (1/z > 0.5)
fcom ds:dword ptr[float_point5]
add edi,ecx
mov edx,ds:dword ptr[espan_t_u+esi]
add edx,edx ; word count
mov ecx,ds:dword ptr[espan_t_count+esi]
add edi,edx ; pdest = &pdestspan[scans->u];
push esi ; preserve spans pointer
fnstsw ax
test ah,045h
jz LClamp
fmul ds:dword ptr[Float2ToThe31nd]
fistp ds:dword ptr[izi] ; note: we are relying on FP exceptions being turned
; off here to avoid problems when the span is closer
; than 1/(2**31)
mov edx,ds:dword ptr[izi]
; at this point:
; %ebx = izistep
; %ecx = count
; %edx = izi
; %edi = pdest
LZDraw:
; do a single pixel up front, if necessary to dword align the destination
test edi,2
jz LFMiddle
mov eax,edx
add edx,ebx
shr eax,16
dec ecx
mov ds:word ptr[edi],ax
add edi,2
; do middle a pair of aligned dwords at a time
LFMiddle:
push ecx
shr ecx,1 ; count / 2
jz LFLast ; no aligned dwords to do
shr ecx,1 ; (count / 2) / 2
jnc LFMiddleLoop ; even number of aligned dwords to do
mov eax,edx
add edx,ebx
shr eax,16
mov esi,edx
add edx,ebx
and esi,0FFFF0000h
or eax,esi
mov ds:dword ptr[edi],eax
add edi,4
and ecx,ecx
jz LFLast
LFMiddleLoop:
mov eax,edx
add edx,ebx
shr eax,16
mov esi,edx
add edx,ebx
and esi,0FFFF0000h
or eax,esi
mov ebp,edx
mov ds:dword ptr[edi],eax
add edx,ebx
shr ebp,16
mov esi,edx
add edx,ebx
and esi,0FFFF0000h
or ebp,esi
mov ds:dword ptr[4+edi],ebp ; FIXME: eliminate register contention
add edi,8
dec ecx
jnz LFMiddleLoop
LFLast:
pop ecx ; retrieve count
pop esi ; retrieve span pointer
; do the last, unaligned pixel, if there is one
and ecx,1 ; is there an odd pixel left to do?
jz LFSpanDone ; no
shr edx,16
mov ds:word ptr[edi],dx ; do the final pixel's z
LFSpanDone:
mov esi,ds:dword ptr[espan_t_pnext+esi]
test esi,esi
jnz LFSpanLoop
jmp LFDone
LFNegSpan:
fmul ds:dword ptr[FloatMinus2ToThe31nd]
fistp ds:dword ptr[izistep] ; note: we are relying on FP exceptions being turned
; off here to avoid range problems
mov ebx,ds:dword ptr[izistep] ; remains loaded for all spans
LFNegSpanLoop:
; set up the initial 1/z value
fild ds:dword ptr[espan_t_v+esi]
fild ds:dword ptr[espan_t_u+esi]
mov ecx,ds:dword ptr[espan_t_v+esi]
mov edi,ds:dword ptr[_d_pzbuffer]
fmul ds:dword ptr[_d_zistepu]
fxch st(1)
fmul ds:dword ptr[_d_zistepv]
fxch st(1)
fadd ds:dword ptr[_d_ziorigin]
imul ecx,ds:dword ptr[_d_zrowbytes]
faddp st(1),st(0)
; clamp if z is nearer than 2 (1/z > 0.5)
fcom ds:dword ptr[float_point5]
add edi,ecx
mov edx,ds:dword ptr[espan_t_u+esi]
add edx,edx ; word count
mov ecx,ds:dword ptr[espan_t_count+esi]
add edi,edx ; pdest = &pdestspan[scans->u];
push esi ; preserve spans pointer
fnstsw ax
test ah,045h
jz LClampNeg
fmul ds:dword ptr[Float2ToThe31nd]
fistp ds:dword ptr[izi] ; note: we are relying on FP exceptions being turned
; off here to avoid problems when the span is closer
; than 1/(2**31)
mov edx,ds:dword ptr[izi]
; at this point:
; %ebx = izistep
; %ecx = count
; %edx = izi
; %edi = pdest
LZDrawNeg:
; do a single pixel up front, if necessary to dword align the destination
test edi,2
jz LFNegMiddle
mov eax,edx
sub edx,ebx
shr eax,16
dec ecx
mov ds:word ptr[edi],ax
add edi,2
; do middle a pair of aligned dwords at a time
LFNegMiddle:
push ecx
shr ecx,1 ; count / 2
jz LFNegLast ; no aligned dwords to do
shr ecx,1 ; (count / 2) / 2
jnc LFNegMiddleLoop ; even number of aligned dwords to do
mov eax,edx
sub edx,ebx
shr eax,16
mov esi,edx
sub edx,ebx
and esi,0FFFF0000h
or eax,esi
mov ds:dword ptr[edi],eax
add edi,4
and ecx,ecx
jz LFNegLast
LFNegMiddleLoop:
mov eax,edx
sub edx,ebx
shr eax,16
mov esi,edx
sub edx,ebx
and esi,0FFFF0000h
or eax,esi
mov ebp,edx
mov ds:dword ptr[edi],eax
sub edx,ebx
shr ebp,16
mov esi,edx
sub edx,ebx
and esi,0FFFF0000h
or ebp,esi
mov ds:dword ptr[4+edi],ebp ; FIXME: eliminate register contention
add edi,8
dec ecx
jnz LFNegMiddleLoop
LFNegLast:
pop ecx ; retrieve count
pop esi ; retrieve span pointer
; do the last, unaligned pixel, if there is one
and ecx,1 ; is there an odd pixel left to do?
jz LFNegSpanDone ; no
shr edx,16
mov ds:word ptr[edi],dx ; do the final pixel's z
LFNegSpanDone:
mov esi,ds:dword ptr[espan_t_pnext+esi]
test esi,esi
jnz LFNegSpanLoop
LFDone:
pop ebx ; restore register variables
pop esi
pop edi
pop ebp ; restore the caller's stack frame
ret
_TEXT ENDS
endif ;id386
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -