brender-1997/pentprim/T15_PIZP.ASM

411 lines
8.7 KiB
NASM
Raw Normal View History

2022-05-03 16:30:35 -05:00
;; Copyright (c) 1992,1993-1995 Argonaut Technologies Limited. All rights reserved.
;;
;; $Id: T15_PIZP.ASM 1.2 1996/11/14 14:44:16 NIKH Exp $
;; $Locker: $
;;
;; Scanline loop for 15 bit perpsective correct texture mapping
;;
.386p
.model c,flat
include drv.inc
.data
z dd ?
i dd ?
du_numerator dd ?
dv_numerator dd ?
u_numerator dd ?
v_numerator dd ?
zdest dd ?
dest dd ?
dest2 dd ?
source dd ?
denominator dd ?
dz dd ?
align 4
.code
; Smoothly lit perspective texture mapping
ScanLinePIZ2TIP macro name,pre,incu,decu,incv,decv,post1,post2,BLEND
name proc
pushad
; Copy various parameters into registers
mov esi,work.pu.current
mov ebx,work.pv.current
mov eax,work.pu.grad_x
mov edi,work.pv.grad_x
mov dv_numerator,edi
mov ecx,work.pi.current
mov edx,work.pq.current
mov v_numerator,ebx
mov denominator,edx
mov i,ecx
mov ecx,work.pz.current
mov z,ecx
mov ecx,work.tsl.zstart
mov zdest,ecx
mov ebp,work.tsl._end
mov du_numerator,eax
mov edi,work.tsl.start
mov eax,work.tsl.source
cmp edi,ebp
mov ebp,zdest
ja rtol ; Jump if right to left
; Left to right scan
mov dest,edi
next_pixelb:
jae L50 ; Jump if end of scan
mov source,eax ; Free up eax
; Texel fetch and store section
; z buffer test
mov dl,[ebp]
mov ebx,z ; Get new z value
mov dh,1[ebp]
ror ebx,16
cmp bx,dx
ja L34 ; Jump if new pixel behind old
mov edx,work.texture.base
xor ecx,ecx
;; Get texel and test for transparency
mov cl,[eax+edx]
if 1
test cl,cl
jz L34
endif
;; Store texel and z
mov eax,work.shade_table
mov ch,byte ptr i+2
lea eax,[2*ecx+eax]
if BLEND
mov cx,[eax] ; Get lit texel
mov dx,[edi] ; Get screen pixel
if BLEND-16
shr ecx,1 ; Halve src & dest colours
and edx,07bdeh ;
shr edx,1 ;
and ecx,03defh ;
else
shr ecx,1 ; Halve src & dest colours
and edx,0f7deh ;
shr edx,1 ;
and ecx,07befh ;
endif
add ecx,edx ; Add together to blend them
else
mov [ebp],bx ; Store new z
mov cx,[eax] ; Get lit texel
endif
mov [edi],cx ; Store texel
L34:
ror ebx,16
mov edx,work.pz.grad_x ; Get z step
add ebp,2 ; zdest++
add ebx,edx ; z += dz
mov edx,i ; Get lighting
mov eax,work.pi.grad_x
add edx,eax ; i += di
mov i,edx
L34a:
lea edi,2[edi]
if 1
cmp edi,work.tsl._end
jae L50
endif
mov edx,denominator
mov dest,edi
mov edi,dv_numerator
mov z,ebx
mov zdest,ebp
mov ecx,work.pq.grad_x
mov ebp,du_numerator
mov ebx,v_numerator
mov eax,source ; Restore eax
; Perspective calculation section
pre
sub esi,ebp
add edx,ecx
cmp esi,edx
jl L36 ; Jump if u not too large
mov ecx,work.pq.grad_x
mov ebp,du_numerator
sub esi,edx
incufloop:
incu ; Increment u
add ebp,ecx
sub esi,edx
jge incufloop
add esi,edx
mov du_numerator,ebp
jmp L37
L36:
test esi,esi
jge L37
mov ebp,du_numerator
decufloop:
decu
sub ebp,work.pq.grad_x
add esi,edx
jnc decufloop
mov du_numerator,ebp
L37:
sub ebx,edi
jl decvf
L40a:
cmp ebx,edx
jge incvf ; Jump if v not too small
jmp L40
decvf:
mov ebp,work.pq.grad_x
decvfloop:
decv ; Decrement v
sub edi,ebp
add ebx,edx
jnc decvfloop
mov dv_numerator,edi
L40:
post1
post2
mov denominator,edx
mov v_numerator,ebx
mov edi,dest
cmp edi,work.tsl._end
mov ebp,zdest
jmp next_pixelb
; Right to left
rtol:
mov dest,edi
next_pixelbr:
jbe L50 ; Jump if end of scan
mov source,eax ; Free up eax
; z buffer test
mov dl,[ebp]
mov ebx,z ; Get new z value
mov dh,1[ebp]
ror ebx,16
cmp bx,dx
ja R34 ; Jump if new pixel behind old
mov edx,work.texture.base
xor ecx,ecx
;; Get texel and test for transparency
mov cl,[edx+eax]
if 1
test cl,cl ; Transparent?
jz R34
endif
;; Store texel and z
mov eax,work.shade_table
mov ch,byte ptr i+2
lea eax,[2*ecx+eax]
if BLEND
mov cx,[eax] ; Get lit texel
mov dx,[edi] ; Get screen pixel
if BLEND-16
shr ecx,1 ; Halve src & dest colours
and edx,07bdeh ;
shr edx,1 ;
and ecx,03defh ;
else
shr ecx,1 ; Halve src & dest colours
and edx,0f7deh ;
shr edx,1 ;
and ecx,07befh ;
endif
add ecx,edx ; Add together to blend them
else
mov [ebp],bx ; Store new z
mov cx,[eax] ; Get lit texel
endif
mov [edi],cx ; Store texel
R34:
sub ebp,2 ; zdest++
;; Update lighting and z
ror ebx,16
mov edx,work.pz.grad_x ; Get z step
mov eax,work.pi.grad_x
sub ebx,edx ; z += dz
mov edx,i ; Get lighting
sub edx,eax ; i += di
mov i,edx
R34a:
lea edi,(-2)[edi]
if 1
cmp edi,work.tsl._end
jbe L50
endif
mov edx,denominator
mov dest,edi
mov edi,dv_numerator
mov z,ebx
mov zdest,ebp
mov ecx,work.pq.grad_x
mov ebp,du_numerator
mov ebx,v_numerator
mov eax,source ; Restore eax
; Core perspective calculations
pre
add esi,ebp
sub edx,ecx
cmp esi,edx
jge incub ; Jump if u not too large
R36:
test esi,esi
jl decub
R37:
add ebx,edi
jl decvb
cmp ebx,edx
jge incvb ; Jump if v not too small
R40:
post1
post2
mov denominator,edx
mov v_numerator,ebx
mov edi,dest
cmp edi,work.tsl._end
mov ebp,zdest
jmp next_pixelbr
L50:
popad
ret
incvf:
mov ecx,work.pq.grad_x
sub ebx,edx
incvfloop:
incv ; Increment v
add edi,ecx
sub ebx,edx
jge incvfloop
add ebx,edx
mov dv_numerator,edi
jmp L40
; Back
decub:
mov ebp,du_numerator
decubloop:
decu
sub ebp,work.pq.grad_x
add esi,edx
jnc decubloop
mov du_numerator,ebp
jmp R37
incub:
mov ecx,work.pq.grad_x
mov ebp,du_numerator
sub esi,edx
incubloop:
incu ; Increment u
add ebp,ecx
sub esi,edx
jge incubloop
add esi,edx
mov du_numerator,ebp
jmp R37
decvb:
mov ebp,work.pq.grad_x
decvbloop:
decv ; Decrement v
sub edi,ebp
add ebx,edx
jnc decvbloop
mov dv_numerator,edi
jmp R40
incvb:
mov ecx,work.pq.grad_x
sub ebx,edx
incvbloop:
incv ; Increment v
add edi,ecx
sub ebx,edx
jge incvbloop
add ebx,edx
mov dv_numerator,edi
jmp R40
name endp
endm
if PARTS and PART_15Z
ScanLinePIZ2TIP ScanLinePIZ2TIP256_RGB_555,\
<>,\
<inc al>,<dec al>,<inc ah>,<dec ah>,\
<>,<>
ScanLinePIZ2TIP ScanLinePIZ2TIPB256_RGB_555,\
<>,\
<inc al>,<dec al>,<inc ah>,<dec ah>,\
<>,<>,15
endif
if PARTS and PART_16Z
ScanLinePIZ2TIP ScanLinePIZ2TIPB256_RGB_565,\
<>,\
<inc al>,<dec al>,<inc ah>,<dec ah>,\
<>,<>,16
endif
end