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]
;;     dec        bx
     cmp	ax,[size_y]
     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]
   ;;  dec        bx
     cmp	.x1,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
    @@:
     cmp	.x2,SIZE_X
     jl 	@f
     mov	.x2,SIZE_X
    @@:
     mov	edx,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