400 lines
7.7 KiB
PHP
400 lines
7.7 KiB
PHP
CATMULL_SHIFT equ 16
|
|
|
|
|
|
flat_triangle_z:
|
|
; procedure drawing triangle with Z cordinate interpolation ------
|
|
; (Catmull alghoritm)--------------------------------------------
|
|
; ----------------in - eax - x1 shl 16 + y1 ----------------------
|
|
; -------------------- ebx - x2 shl 16 + y2 ----------------------
|
|
; -------------------- ecx - x3 shl 16 + y3 ----------------------
|
|
; -------------------- edx - color 0x00RRGGBB --------------------
|
|
; -------------------- esi - pointer to Z-buffer -----------------
|
|
; -------------------- edi - pointer to screen buffer-------------
|
|
; -------------------- stack : z coordinates
|
|
; -------------------- Z-buffer : each z variable as dword
|
|
; -------------------- (Z coor. as word) shl CATMULL_SHIFT
|
|
.z1 equ word[ebp+4]
|
|
.z2 equ word[ebp+6] ; each z coordinate as word integer
|
|
.z3 equ word[ebp+8]
|
|
|
|
.col equ dword[ebp-4]
|
|
.x1 equ word[ebp-6]
|
|
.y1 equ word[ebp-8]
|
|
.x2 equ word[ebp-10]
|
|
.y2 equ word[ebp-12]
|
|
.x3 equ word[ebp-14]
|
|
.y3 equ word[ebp-16]
|
|
|
|
.dx12 equ dword[ebp-20]
|
|
;.dz12 equ dword[ebp-24]
|
|
.dx13 equ dword[ebp-24]
|
|
.dz13 equ dword[ebp-28]
|
|
.dz12 equ dword[ebp-32]
|
|
;.dz13 equ dword[ebp-32]
|
|
.dx23 equ dword[ebp-36]
|
|
.dz13M equ [ebp-40]
|
|
.dz23 equ dword[ebp-44]
|
|
.zz1 equ dword[ebp-48]
|
|
.zz2 equ dword[ebp-52]
|
|
.zz2M equ qword[ebp-52]
|
|
.dz12M equ qword[ebp-32]
|
|
.dz23M equ qword[ebp-44]
|
|
;if Ext>=MMX
|
|
; emms
|
|
;end if
|
|
mov ebp,esp
|
|
|
|
push edx ; store edx in variable .col
|
|
.sort2:
|
|
cmp ax,bx
|
|
jle .sort1
|
|
xchg eax,ebx
|
|
mov dx,.z1
|
|
xchg dx,.z2
|
|
mov .z1,dx
|
|
.sort1:
|
|
cmp bx,cx
|
|
jle .sort3
|
|
xchg ebx,ecx
|
|
mov dx,.z2
|
|
xchg dx,.z3
|
|
mov .z2,dx
|
|
jmp .sort2
|
|
.sort3:
|
|
push eax ; store triangle coordinates in 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 .ft_loop2_end
|
|
; cmp ax,SIZE_Y
|
|
; jle @f
|
|
; cmp bx,SIZE_Y
|
|
; jle @f
|
|
; cmp cx,SIZE_Y
|
|
; jge @f
|
|
; ror eax,16
|
|
; ror ebx,16
|
|
; ror ecx,16
|
|
; cmp ax,SIZE_X
|
|
; jle @f
|
|
; cmp bx,SIZE_X
|
|
; jle @f
|
|
; cmp cx,SIZE_X
|
|
; jle @f
|
|
; jmp .ft_loop2_end
|
|
;@@:
|
|
sub esp,52-12
|
|
|
|
mov bx,.y2 ; calc delta 12
|
|
sub bx,.y1
|
|
jnz .ft_dx12_make
|
|
mov .dx12,0
|
|
mov .dz12,0
|
|
jmp .ft_dx12_done
|
|
.ft_dx12_make:
|
|
mov ax,.x2
|
|
sub ax,.x1
|
|
cwde
|
|
movsx ebx,bx
|
|
shl eax,ROUND
|
|
cdq
|
|
idiv ebx
|
|
mov .dx12,eax
|
|
|
|
mov ax,.z2
|
|
sub ax,.z1
|
|
cwde
|
|
shl eax,CATMULL_SHIFT
|
|
cdq
|
|
idiv ebx
|
|
mov .dz12,eax
|
|
.ft_dx12_done:
|
|
mov bx,.y3 ; calc delta 13
|
|
sub bx,.y1
|
|
jnz .ft_dx13_make
|
|
mov .dx13,0
|
|
mov .dz13,0
|
|
mov dword .dz13M,0
|
|
jmp .ft_dx13_done
|
|
.ft_dx13_make:
|
|
mov ax,.x3
|
|
sub ax,.x1
|
|
cwde
|
|
movsx ebx,bx
|
|
shl eax,ROUND
|
|
cdq
|
|
idiv ebx
|
|
mov .dx13,eax
|
|
|
|
mov ax,.z3
|
|
sub ax,.z1
|
|
cwde
|
|
shl eax,CATMULL_SHIFT
|
|
cdq
|
|
idiv ebx
|
|
mov .dz13,eax
|
|
mov dword .dz13M,eax
|
|
.ft_dx13_done:
|
|
mov bx,.y3 ; calc delta 23
|
|
sub bx,.y2
|
|
jnz .gt_dx23_make
|
|
mov .dx23,0
|
|
mov .dz23,0
|
|
jmp .gt_dx23_done
|
|
.gt_dx23_make:
|
|
mov ax,.x3
|
|
sub ax,.x2
|
|
cwde
|
|
movsx ebx,bx
|
|
shl eax,ROUND
|
|
cdq
|
|
idiv ebx
|
|
mov .dx23,eax
|
|
|
|
mov ax,.z3
|
|
sub ax,.z2
|
|
cwde
|
|
shl eax,CATMULL_SHIFT
|
|
cdq
|
|
idiv ebx
|
|
mov .dz23,eax
|
|
.gt_dx23_done:
|
|
|
|
movsx edx,.z1
|
|
shl edx,CATMULL_SHIFT
|
|
mov .zz1,edx
|
|
mov .zz2,edx
|
|
movsx eax,.x1
|
|
shl eax,ROUND ; eax - x1
|
|
mov ebx,eax ; ebx - x2
|
|
;if Ext>=MMX
|
|
; movq mm0,.zz2M
|
|
;end if
|
|
mov cx,.y1
|
|
cmp cx,.y2
|
|
jge .ft_loop1_end
|
|
.ft_loop1:
|
|
|
|
pushad
|
|
|
|
push .col
|
|
push cx ; y
|
|
sar ebx,ROUND
|
|
push bx ; x2
|
|
sar eax,ROUND
|
|
push ax ; x1
|
|
;if Ext>=MMX
|
|
; sub esp,8
|
|
; movq [esp],mm0
|
|
;else
|
|
push .zz2 ; z2 shl CATMULL_SHIFT
|
|
push .zz1 ; z1 shl CATMULL_SHIFT
|
|
;end if
|
|
call flat_line_z
|
|
|
|
popad
|
|
|
|
add eax,.dx13
|
|
add ebx,.dx12
|
|
;if Ext>=MMX
|
|
; paddd mm0,.dz12M
|
|
;else
|
|
|
|
mov edx,.dz13
|
|
add .zz1,edx
|
|
mov edx,.dz12
|
|
add .zz2,edx
|
|
;end if
|
|
inc cx
|
|
cmp cx,.y2
|
|
jl .ft_loop1
|
|
.ft_loop1_end:
|
|
|
|
movsx edx,.z2
|
|
shl edx,CATMULL_SHIFT
|
|
mov .zz2,edx
|
|
movsx ebx,.x2
|
|
shl ebx,ROUND
|
|
;if Ext>=MMX
|
|
; movq mm0,.zz2M
|
|
;; push .dz13 ; exchange
|
|
;; pop .dz12
|
|
;; push .dz23 ; exchange
|
|
;; pop .dz13
|
|
;end if
|
|
mov cx,.y2
|
|
cmp cx,.y3
|
|
jge .ft_loop2_end
|
|
.ft_loop2:
|
|
pushad
|
|
|
|
push .col
|
|
push cx
|
|
sar ebx,ROUND
|
|
push bx
|
|
sar eax,ROUND
|
|
push ax ; x1
|
|
;if Ext>=MMX
|
|
; sub esp,8
|
|
; movq [esp],mm0
|
|
;else
|
|
push .zz2 ; z2 shl CATMULL_SHIFT
|
|
push .zz1 ; z1 shl CATMULL_SHIFT
|
|
;end if
|
|
call flat_line_z
|
|
|
|
popad
|
|
|
|
add eax,.dx13
|
|
add ebx,.dx23
|
|
;if Ext>=MMX
|
|
; paddd mm0,.dz23M
|
|
;else
|
|
mov edx,.dz13
|
|
add .zz1,edx
|
|
mov edx,.dz23
|
|
add .zz2,edx
|
|
|
|
; mov edx,.dz13
|
|
; add .zz1,edx
|
|
; mov edx,.dz12
|
|
; add .zz2,edx
|
|
;end if
|
|
inc cx
|
|
cmp cx,.y3
|
|
jl .ft_loop2
|
|
.ft_loop2_end:
|
|
|
|
mov esp,ebp
|
|
ret 6
|
|
|
|
flat_line_z:
|
|
;----------------
|
|
;-------------in edi - pointer to screen buffer ----------------------------------
|
|
;--------------- esi - pointer to z-buffer (each Z varible dword)-----------------
|
|
;----------stack - (each z coordinate shifted shl CATMULL_SHIFT)------------------
|
|
.z1 equ dword [ebp+4]
|
|
.z2 equ dword [ebp+8]
|
|
.x1 equ word [ebp+12]
|
|
.x2 equ word [ebp+14]
|
|
.y equ word [ebp+16]
|
|
.col equ dword [ebp+18]
|
|
|
|
.dz equ dword [ebp-4]
|
|
|
|
mov ebp,esp
|
|
;; sub esp,4
|
|
mov ax,.y
|
|
or ax,ax
|
|
jl .fl_quit
|
|
mov bx,[size_y_var]
|
|
dec bx
|
|
cmp ax,bx ;[size_y_var]
|
|
; cmp ax,SIZE_Y-1
|
|
jg .fl_quit
|
|
|
|
; cmp .x1,0
|
|
; jge .fl_ok1
|
|
; cmp .x2,0
|
|
; jl .fl_quit
|
|
; .fl_ok1:
|
|
; cmp .x1,SIZE_X
|
|
; jle .fl_ok2
|
|
; cmp .x2,SIZE_X
|
|
; jg .fl_quit
|
|
; .fl_ok2:
|
|
mov ax,.x1
|
|
cmp ax,.x2
|
|
je .fl_quit
|
|
jl .fl_ok
|
|
|
|
xchg ax,.x2
|
|
mov .x1,ax
|
|
mov edx,.z1
|
|
xchg edx,.z2
|
|
mov .z1,edx
|
|
.fl_ok:
|
|
mov bx,[size_x_var]
|
|
dec bx
|
|
cmp .x1,bx ;SIZE_X-1
|
|
jg .fl_quit
|
|
cmp .x2,0
|
|
jle .fl_quit
|
|
|
|
mov eax,.z2
|
|
sub eax,.z1
|
|
cdq
|
|
mov bx,.x2
|
|
sub bx,.x1
|
|
movsx ebx,bx
|
|
idiv ebx
|
|
;; mov .dz,eax ; calculated delta - shifted .dz
|
|
push eax
|
|
|
|
cmp .x1,0
|
|
jge @f
|
|
movsx ebx,.x1
|
|
neg ebx
|
|
imul ebx
|
|
add .z1,eax
|
|
mov .x1,0
|
|
@@:
|
|
movzx edx,word[size_x_var]
|
|
cmp .x2,dx ;[size_x_var] ;SIZE_X
|
|
jl @f
|
|
mov .x2,dx ;[size_x_var] ;SIZE_X
|
|
@@:
|
|
; movzx edx,[size_x_var] ;SIZE_X
|
|
movsx eax,.y
|
|
mul edx ; edi = edi + (SIZE_X * y + x1)*3
|
|
movsx edx,.x1
|
|
add eax,edx
|
|
push eax
|
|
lea eax,[eax*3]
|
|
add edi,eax ; esi = esi + (SIZE_X * y + x1)*4
|
|
pop eax
|
|
shl eax,2
|
|
add esi,eax
|
|
|
|
mov cx,.x2
|
|
sub cx,.x1
|
|
movzx ecx,cx
|
|
|
|
mov eax,.col
|
|
mov ebx,.z1 ; ebx : curr. z
|
|
mov edx,.dz
|
|
dec ecx
|
|
jecxz .draw_last
|
|
.ddraw:
|
|
cmp ebx,dword[esi]
|
|
; cmovl [edi],eax
|
|
; cmovl [esi],ebx
|
|
jge @f
|
|
stosd
|
|
dec edi
|
|
mov dword[esi],ebx
|
|
jmp .no_skip
|
|
@@:
|
|
add edi,3
|
|
.no_skip:
|
|
add esi,4
|
|
add ebx,edx
|
|
loop .ddraw
|
|
|
|
.draw_last:
|
|
cmp ebx,dword[esi]
|
|
jge .fl_quit
|
|
stosw
|
|
shr eax,16
|
|
stosb
|
|
mov dword[esi],ebx
|
|
|
|
.fl_quit:
|
|
|
|
mov esp,ebp
|
|
ret 18
|