Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 2270 → Rev 2271

/programs/demos/3dsheart/trunk/tex_cat.ASM
0,0 → 1,585
;TEX_X = 512
;TEX_Y = 512
;ROUND equ 8
;SIZE_X = 512
;SIZE_Y = 512
;TEX_SHIFT = 9
CATMULL_SHIFT equ 8
 
;------------------------------------------------------------------------
;- Procedure drawing textured triangle using Catmull Z-buffer algorithm -
;------------------------------------------------------------------------
tex_triangle_z:
;----------in - eax - x1 shl 16 + y1
;-------------- ebx - x2 shl 16 + y2
;---------------ecx - x3 shl 16 + y3
;---------------edx - pointer to Z-buffer
;---------------esi - pointer to texture buffer
;---------------edi - pointer to screen buffer
;-------------stack - texture coordinates
;------------------ - z coordinates
.tex_x1 equ ebp+4
.tex_y1 equ ebp+6
.tex_x2 equ ebp+8
.tex_y2 equ ebp+10
.tex_x3 equ ebp+12
.tex_y3 equ ebp+14
.z1 equ word[ebp+16]
.z2 equ word[ebp+18]
.z3 equ word[ebp+20]
 
.tex_ptr equ dword[ebp-4] ; pointer to texture
.z_ptr equ dword[ebp-8] ; pointer to z-buffer
.x1 equ word[ebp-10]
.y1 equ word[ebp-12]
.x2 equ word[ebp-14]
.y2 equ word[ebp-16]
.x3 equ word[ebp-18]
.y3 equ word[ebp-20]
 
.dx12 equ dword[ebp-24]
.tex_dx12 equ dword[ebp-28]
.tex_dy12 equ dword[ebp-32]
.dz12 equ dword[ebp-36]
 
.dx13 equ dword[ebp-40]
.tex_dx13 equ dword[ebp-44]
.tex_dy13 equ dword[ebp-48]
.dz13 equ dword[ebp-52]
 
.dx23 equ dword[ebp-56]
.tex_dx23 equ dword[ebp-60]
.tex_dy23 equ dword[ebp-64]
.dz23 equ dword[ebp-68]
 
.scan_x1 equ dword[ebp-72]
.scan_x2 equ dword[ebp-76]
.scan_y1 equ dword[ebp-80]
.scan_y2 equ dword[ebp-84]
.cz1 equ dword[ebp-88]
.cz2 equ dword[ebp-92]
 
mov ebp,esp
push esi ; store memory pointers
push edx
.tt_sort3:
cmp ax,bx ;sort all parameters
jle .tt_sort1
xchg eax,ebx
mov edx,dword [.tex_x1]
xchg edx,dword [.tex_x2]
mov dword[.tex_x1],edx
mov dx,.z1
xchg dx,.z2
mov .z1,dx
.tt_sort1:
cmp bx,cx
jle .tt_sort2
xchg ebx,ecx
mov edx,dword [.tex_x2]
xchg edx,dword [.tex_x3]
mov dword [.tex_x2],edx
mov dx,.z2
xchg dx,.z3
mov .z2,dx
jmp .tt_sort3
.tt_sort2:
 
push eax ; and store to user friendly variables
push ebx
push ecx
 
mov edx,80008000h ; eax,ebx,ecx are ANDd together into edx which means that
and edx,ebx ; if *all* of them are negative a sign flag is raised
and edx,ecx
and edx,eax
test edx,80008000h ; Check both X&Y at once
jne .tt_loop2_end
cmp ax,SIZE_Y
jl @f
cmp bx,SIZE_Y
jl @f
cmp cx,SIZE_Y
jl @f
ror eax,16
ror ebx,16
ror ecx,16
cmp ax,SIZE_X
jl @f
cmp bx,SIZE_X
jl @f
cmp cx,SIZE_X
jl @f
jmp .tt_loop2_end
@@:
mov eax,dword[.tex_x1] ; texture coords must be in [0..TEX_X(Y)]
mov ebx,dword[.tex_x2]
mov ecx,dword[.tex_x3]
mov edx,eax
or edx,ebx
or edx,ecx
test edx,80008000h
jne .tt_loop2_end
cmp ax,TEX_X
jge .tt_loop2_end
cmp bx,TEX_X
jge .tt_loop2_end
cmp cx,TEX_X
jge .tt_loop2_end
ror eax,16
ror ebx,16
ror ecx,16
cmp ax,TEX_Y
jge .tt_loop2_end
cmp bx,TEX_Y
jge .tt_loop2_end
cmp cx,TEX_Y
jge .tt_loop2_end
 
 
movsx ebx,.y2 ; calc delta
sub bx,.y1
jnz .tt_dx12_make
xor edx,edx
mov ecx,4
@@:
push edx
loop @b
jmp .tt_dx12_done
.tt_dx12_make:
mov ax,.x2
sub ax,.x1
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dx12,eax ; dx12 = (x2-x1)/(y2-y1)
push eax
 
mov ax,word[.tex_x2]
sub ax,word[.tex_x1]
cwde
shl eax,ROUND
cdq
idiv ebx
; mov [.tex_dx12],eax ; tex_dx12 = (tex_x2-tex_x1)/(y2-y1)
push eax
 
mov ax,word[.tex_y2]
sub ax,word[.tex_y1]
cwde
shl eax,ROUND
cdq
idiv ebx
; mov [.tex_dy12],eax ; tex_dy12 = (tex_y2-tex_y1)/(y2-y1)
push eax
 
mov ax,.z2
sub ax,.z1
cwde
shl eax,CATMULL_SHIFT
cdq
idiv ebx
push eax
.tt_dx12_done:
 
movsx ebx,.y3 ; calc delta
sub bx,.y1
jnz .tt_dx13_make
xor edx,edx
mov ecx,4
@@:
push edx
loop @b
jmp .tt_dx13_done
.tt_dx13_make:
mov ax,.x3
sub ax,.x1
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dx12,eax ; dx13 = (x3-x1)/(y3-y1)
push eax
 
mov ax,word[.tex_x3]
sub ax,word[.tex_x1]
cwde
shl eax,ROUND
cdq
idiv ebx
; mov [.tex_dx12],eax ; tex_dx13 = (tex_x3-tex_x1)/(y3-y1)
push eax
 
mov ax,word[.tex_y3]
sub ax,word[.tex_y1]
cwde
shl eax,ROUND
cdq
idiv ebx
; mov [.tex_dy12],eax ; tex_dy13 = (tex_y3-tex_y1)/(y3-y1)
push eax
 
mov ax,.z3
sub ax,.z1
cwde
shl eax,CATMULL_SHIFT
cdq
idiv ebx
push eax
.tt_dx13_done:
 
mov bx,.y3 ; calc delta
sub bx,.y2
jnz .tt_dx23_make
xor edx,edx
mov ecx,4
@@:
push edx
loop @b
jmp .tt_dx23_done
.tt_dx23_make:
mov ax,.x3
sub ax,.x2
cwde
shl eax,ROUND
cdq
movzx ebx,bx
idiv ebx
; mov .dx23,eax ; dx23 = (x3-x2)/(y3-y2)
push eax
 
mov ax,word[.tex_x3]
sub ax,word[.tex_x2]
cwde
shl eax,ROUND
cdq
idiv ebx
; mov [.tex_dx23],eax ; tex_dx23 = (tex_x3-tex_x2)/(y3-y2)
push eax
 
mov ax,word[.tex_y3]
sub ax,word[.tex_y2]
cwde
shl eax,ROUND
cdq
idiv ebx
; mov [.tex_dy23],eax ; tex_dy23 = (tex_y3-tex_y2)/(y3-y2)
push eax
 
mov ax,.z3
sub ax,.z2
cwde
shl eax,CATMULL_SHIFT
cdq
idiv ebx
push eax
.tt_dx23_done:
 
movsx eax,.x1 ;eax - cur x1
shl eax,ROUND ;ebx - cur x2
mov ebx,eax
 
movsx edx, word[.tex_x1]
shl edx,ROUND
; mov [.scan_x1],edx
; mov [.scan_x2],edx
push edx
push edx
movsx edx, word[.tex_y1]
shl edx,ROUND
; mov [.scan_y1],edx
; mov [.scan_y2],edx
push edx
push edx
movsx edx,.z1
shl edx,CATMULL_SHIFT
push edx
push edx
mov cx,.y1
cmp cx,.y2
jge .tt_loop1_end
 
.tt_loop1:
pushad
 
push .z_ptr
push .cz1 ; z coords shifted shl catmull_shift
push .cz2
mov edx, .scan_y2
sar edx, ROUND
push dx
mov edx, .scan_x2
sar edx, ROUND
push dx
mov edx, .scan_y1
sar edx, ROUND
push dx
mov edx, .scan_x1
sar edx, ROUND
push dx
push esi ;[.tex_ptr]
 
push cx
sar ebx,ROUND
push bx
sar eax,ROUND
push ax
call textured_line_z
 
popad
mov edx,.dz13
add .cz1,edx
mov edx,.dz12
add .cz2,edx
 
mov edx, .tex_dx13
add .scan_x1, edx
mov edx, .tex_dx12
add .scan_x2, edx
mov edx, .tex_dy13
add .scan_y1, edx
mov edx, .tex_dy12
add .scan_y2, edx
 
add eax, .dx13
add ebx, .dx12
inc cx
cmp cx,.y2
jl .tt_loop1
 
.tt_loop1_end:
 
 
mov cx,.y2
cmp cx,.y3
jge .tt_loop2_end
 
movsx ebx,.x2
shl ebx,ROUND
movsx edx,.z2
shl edx,CATMULL_SHIFT
mov .cz2,edx
movzx edx, word [.tex_x2]
shl edx,ROUND
mov .scan_x2,edx
movzx edx, word[.tex_y2]
shl edx,ROUND
mov .scan_y2,edx
 
.tt_loop2:
 
pushad
 
push .z_ptr
push .cz1 ; z coords shifted shl catmull_shift
push .cz2
mov edx, .scan_y2
sar edx, ROUND
push dx
mov edx, .scan_x2
sar edx, ROUND
push dx
mov edx, .scan_y1
sar edx, ROUND
push dx
mov edx, .scan_x1
sar edx, ROUND
push dx
push esi ;[.tex_ptr]
 
push cx
sar ebx,ROUND
push bx
sar eax,ROUND
push ax
call textured_line_z
 
popad
 
 
mov edx,.dz13
add .cz1,edx
mov edx,.dz23
add .cz2,edx
 
mov edx, .tex_dx13
add .scan_x1, edx
mov edx, .tex_dx23
add .scan_x2, edx
mov edx, .tex_dy13
add .scan_y1, edx
mov edx, .tex_dy23
add .scan_y2, edx
 
add eax, .dx13
add ebx, .dx23
inc cx
cmp cx,.y3
jl .tt_loop2
 
.tt_loop2_end:
 
.tt_end:
mov esp,ebp
ret 18
 
textured_line_z:
;-----in -edi screen buffer pointer
;------------ stack:
.x1 equ word [ebp+4]
.x2 equ word [ebp+6]
.y equ word [ebp+8]
 
.tex_ptr equ dword [ebp+10]
.tex_x1 equ ebp+14
.tex_y1 equ ebp+16
.tex_x2 equ ebp+18
.tex_y2 equ ebp+20
.z2 equ dword [ebp+22] ;z1, z2 coords shifted shl CATMULL_SHIFT
.z1 equ dword [ebp+26]
.z_ptr equ dword [ebp+30]
 
.tex_dx equ dword [ebp-4]
.tex_dy equ dword [ebp-8]
.dz equ dword [ebp-12]
.cz equ dword [ebp-16]
.c_tex_x equ dword [ebp-20] ; current tex x
 
 
mov ebp,esp
 
mov ax,.y
or ax,ax
jl .tl_quit
cmp ax,SIZE_Y
jge .tl_quit
 
mov ax,.x1
cmp ax,.x2
je .tl_quit
jl .tl_ok
 
xchg ax,.x2 ; sort params
mov .x1,ax
 
mov eax,dword[.tex_x1]
xchg eax,dword[.tex_x2]
mov dword[.tex_x1],eax
 
mov eax,.z1
xchg eax,.z2
mov .z1,eax
.tl_ok:
cmp .x1,SIZE_X
jge .tl_quit
cmp .x2,0
jle .tl_quit
 
mov bx,.x2
sub bx,.x1
movsx ebx,bx
 
mov ax,word[.tex_x2] ; calc .dtx
sub ax,word[.tex_x1]
cwde
shl eax,ROUND
cdq
idiv ebx
push eax
 
mov ax,word[.tex_y2] ; calc .dty
sub ax,word[.tex_y1]
cwde
shl eax,ROUND
cdq
idiv ebx
push eax
 
mov eax,.z2 ; calc .dz
sub eax,.z1
cdq
idiv ebx
push eax
 
cmp .x1,0 ; clipping
jge @f
 
movsx ebx,.x1
neg ebx
imul ebx ; eax = .dz * abs(.x1)
add .z1,eax
mov .x1,0
 
mov eax,.tex_dy
sar eax,ROUND
imul ebx
add word[.tex_y1],ax
 
mov eax,.tex_dx
sar eax,ROUND
imul ebx
add word[.tex_x1],ax
@@:
cmp .x2,SIZE_X
jl @f
mov .x2,SIZE_X
@@:
 
movsx ebx,.y ; calc mem begin in buffers
mov eax,SIZE_X
mul ebx
movsx ebx,.x1
add eax,ebx
mov ebx,eax
 
lea eax,[eax*3]
add edi,eax ; edi - scr buff
shl ebx,2
add .z_ptr,ebx ; z buffer pointer
 
mov cx,.x2
sub cx,.x1
movzx ecx,cx
 
 
movzx eax,word[.tex_x1]
shl eax,ROUND
movzx ebx,word[.tex_y1]
shl ebx,ROUND
push .z1 ; .cz
push eax ;.c_tex_x
.tl_loop:
mov edx,.z_ptr ; eax - temp
mov eax,.cz ; ebx - cur tex y shl ROUND
cmp eax,[edx] ; ecx - l.lenght
jge .skip ; ebx - cur tex_y ; edx - temp
mov esi,ebx ; edi - scr buff
sar esi,ROUND ; esi - tex_ptr temp
shl esi,TEX_SHIFT ; .z_ptr - cur pointer to z buff
mov eax,.c_tex_x ; .cz - cur z coord shl CATMULL_SHIFT
sar eax,ROUND
add esi,eax
and esi,TEXTURE_SIZE
lea esi,[esi*3]
add esi,.tex_ptr
movsd
dec edi
mov eax,.cz
mov esi,.z_ptr
mov dword[esi],eax ; renew z buffer
jmp .no_skip
.skip:
add edi,3
.no_skip:
add .z_ptr,4
mov eax,.dz
add .cz,eax
mov eax,.tex_dx
add .c_tex_x,eax
add ebx,.tex_dy
loop .tl_loop
.tl_quit:
mov esp,ebp
ret 30