ROUND equ 8
CATMULL_SHIFT equ 8
gouraud_triangle_z:
;----procedure drawing gouraud triangle with z coordinate
;----interpolation ( Catmull alghoritm )-----------------
;------------------in - eax - x1 shl 16 + y1 ------------
;---------------------- ebx - x2 shl 16 + y2 ------------
;---------------------- ecx - x3 shl 16 + y3 ------------
;---------------------- esi - pointer to Z-buffer--------
;---------------------- Z-buffer filled with dd variables
;---------------------- shifted CATMULL_SHIFT------------
;---------------------- edi - pointer to screen buffer---
;---------------------- stack : colors-------------------
;----------------- procedure don't save registers !!-----
.col1r equ ebp+4   ; each color as word
.col1g equ ebp+6   ; each z coordinate as word
.col1b equ ebp+8
.z1    equ ebp+10
.col2r equ ebp+12
.col2g equ ebp+14
.col2b equ ebp+16
.z2    equ ebp+18
.col3r equ ebp+20
.col3g equ ebp+22
.col3b equ ebp+24
.z3    equ ebp+26

.x1    equ word[ebp-2]
.y1    equ word[ebp-4]
.x2    equ word[ebp-6]
.y2    equ word[ebp-8]
.x3    equ word[ebp-10]
.y3    equ word[ebp-12]

.dx12  equ dword[ebp-16]
.dz12  equ dword[ebp-20]
.dc12r equ dword[ebp-24]
.dc12g equ dword[ebp-28]
.dc12b equ dword[ebp-32]

.dx13  equ dword[ebp-36]
.dz13  equ dword[ebp-40]
.dc13r equ dword[ebp-44]
.dc13g equ dword[ebp-48]
.dc13b equ dword[ebp-52]

.dx23  equ dword[ebp-56]
.dz23  equ dword[ebp-60]
.dc23r equ dword[ebp-64]
.dc23g equ dword[ebp-68]
.dc23b equ dword[ebp-72]

.c1r   equ dword[ebp-76]
.c1g   equ dword[ebp-80]
.c1b   equ dword[ebp-84]
.c2r   equ dword[ebp-88]
.c2g   equ dword[ebp-92]
.c2b   equ dword[ebp-96]
.zz1   equ dword[ebp-100]
.zz2   equ dword[ebp-104]

       mov     ebp,esp
     ;  sub     esp,84
 .sort3:		  ; sort triangle coordinates...
       cmp     ax,bx
       jle     .sort1
       xchg    eax,ebx
       mov     edx,dword[.col1r]
       xchg    edx,dword[.col2r]
       mov     dword[.col1r],edx
       mov     edx,dword[.col1b]
       xchg    edx,dword[.col2b]
       mov     dword[.col1b],edx
 .sort1:
       cmp	bx,cx
       jle	.sort2
       xchg	ebx,ecx
       mov	edx,dword[.col2r]
       xchg	edx,dword[.col3r]
       mov	dword[.col2r],edx
       mov	edx,dword[.col2b]
       xchg	edx,dword[.col3b]
       mov	dword[.col2b],edx
       jmp .sort3
 .sort2:
       push	eax	     ; store in 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	  .gt_loop2_end

       mov	bx,.y2	     ; calc deltas
       sub	bx,.y1
       jnz	.gt_dx12_make
      ; mov      .dx12,0
      ; mov      .dz12,0
      ; mov      .dc12r,0
      ; mov      .dc12g,0
      ; mov      .dc12b,0
       mov	ecx,5
     @@:
       push	dword 0
       loop	@b
       jmp	.gt_dx12_done
  .gt_dx12_make:
       mov	ax,.x2
       sub	ax,.x1
       cwde
       movsx	ebx,bx
       shl	eax,ROUND
       cdq
       idiv	ebx
 ;      mov      .dx12,eax
       push	 eax

       mov	ax,word[.z2]
       sub	ax,word[.z1]
       cwde
       shl	eax,CATMULL_SHIFT
       cdq
       idiv	ebx
       push	eax

       mov	ax,word[.col2r]
       sub	ax,word[.col1r]
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
      ; mov      .dc12r,eax
       push	  eax
       mov	  ax,word[.col2g]
       sub	  ax,word[.col1g]
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
     ;  mov .dc12g,eax
       push	eax
       mov	ax,word[.col2b]        ;;---
       sub	ax,word[.col1b]
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
      ; mov .dc12b,eax
       push	eax
   .gt_dx12_done:

       mov	bx,.y3	     ; calc deltas
       sub	bx,.y1
       jnz	.gt_dx13_make
      ; mov      .dx13,0
      ; mov      .dz13,0
      ; mov      .dc13r,0
      ; mov      .dc13g,0
      ; mov      .dc13b,0
       mov	ecx,5
     @@:
       push	dword 0
       loop	@b
       jmp	.gt_dx13_done
    .gt_dx13_make:
       mov	ax,.x3
       sub	ax,.x1
       cwde
       movsx	ebx,bx
       shl	eax,ROUND
       cdq
       idiv	ebx
 ;      mov      .dx13,eax
       push	 eax

       mov	ax,word[.z3]
       sub	ax,word[.z1]
       cwde
       shl	eax,CATMULL_SHIFT
       cdq
       idiv	ebx
       push	eax

       mov	ax,word[.col3r]
       sub	ax,word[.col1r]
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
      ; mov      .dc13r,eax
       push	  eax
       mov	  ax,word[.col3g]
       sub	  ax,word[.col1g]
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
     ;  mov .dc13g,eax
       push	eax
       mov	ax,word[.col3b]
       sub	ax,word[.col1b]
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
      ; mov .dc13b,eax
       push	eax
   .gt_dx13_done:

       mov	bx,.y3	     ; calc deltas
       sub	bx,.y2
       jnz	.gt_dx23_make
      ; mov      .dx23,0
      ; mov      .dz23,0
      ; mov      .dc23r,0
      ; mov      .dc23g,0
      ; mov      .dc23b,0
       mov	ecx,5
     @@:
       push	dword 0
       loop	@b
       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
       push	 eax

       mov	ax,word[.z3]
       sub	ax,word[.z2]
       cwde
       shl	eax,CATMULL_SHIFT
       cdq
       idiv	ebx
       push	eax

       mov	ax,word[.col3r]
       sub	ax,word[.col2r]
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
      ; mov     .dc23r,eax
       push	eax
       mov	ax,word[.col3g]
       sub	ax,word[.col2g]
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
     ;  mov .dc23g,eax
       push	eax
       mov	ax,word[.col3b]
       sub	ax,word[.col2b]
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
      ; mov .dc23b,eax
       push	eax
   .gt_dx23_done:
       sub	esp,32

       movsx	eax,.x1 		   ; eax - cur x1
       shl	eax,ROUND		   ; ebx - cur x2
       mov	ebx,eax
       movsx	edx,word[.z1]
       shl	edx,CATMULL_SHIFT
       mov	.zz1,edx
       mov	.zz2,edx
       movzx	edx,word[.col1r]
       shl	edx,ROUND
       mov	.c1r,edx
       mov	.c2r,edx
       movzx	edx,word[.col1g]
       shl	edx,ROUND
       mov	.c1g,edx
       mov	.c2g,edx
       movzx	edx,word[.col1b]
       shl	edx,ROUND
       mov	.c1b,edx
       mov	.c2b,edx
       mov	cx,.y1
       cmp	cx,.y2
       jge	.gt_loop1_end

    .gt_loop1:
       pushad
    ; macro .debug

       mov	edx,.c2r	      ; c2r,c2g,c2b,c1r,c1g,c1b - current colors
       sar	edx,ROUND
       push	dx
       mov	edx,.c2g
       sar	edx,ROUND
       push	dx
       mov	edx,.c2b
       sar	edx,ROUND
       push	dx
       sar	ebx,ROUND    ; x2
       push	bx
       mov	edx,.c1r
       sar	edx,ROUND
       push	dx
       mov	edx,.c1g
       sar	edx,ROUND
       push	dx
       mov	edx,.c1b
       sar	edx,ROUND
       push	dx
       sar	eax,ROUND
       push	ax	      ; x1
       push	cx	      ; y
       push	.zz2
       push	.zz1
       call	gouraud_line_z

       popad

       mov	edx,.dc13r
       add	.c1r,edx
       mov	edx,.dc13g
       add	.c1g,edx
       mov	edx,.dc13b
       add	.c1b,edx
       mov	edx,.dc12r
       add	.c2r,edx
       mov	edx,.dc12g
       add	.c2g,edx
       mov	edx,.dc12b
       add	.c2b,edx
       mov	edx,.dz13
       add	.zz1,edx
       mov	edx,.dz12
       add	.zz2,edx

       add	eax,.dx13
       add	ebx,.dx12
       inc	cx
       cmp	cx,.y2
       jl	.gt_loop1

   .gt_loop1_end:
       mov	cx,.y2
       cmp	cx,.y3
       jge	.gt_loop2_end

       movsx	ebx,.x2 		   ; eax - cur x1
       shl	ebx,ROUND		   ; ebx - cur x2
       movsx	edx,word[.z2]
       shl	edx,CATMULL_SHIFT
       mov	.zz2,edx
       movzx	edx,word[.col2r]
       shl	edx,ROUND
       mov	.c2r,edx
       movzx	edx,word[.col2g]
       shl	edx,ROUND
       mov	.c2g,edx
       movzx	edx,word[.col2b]
       shl	edx,ROUND
       mov	.c2b,edx

    .gt_loop2:
       pushad
    ; macro .debug

       mov	edx,.c2r	      ; c2r,c2g,c2b,c1r,c1g,c1b - current colors
       sar	edx,ROUND
       push	dx
       mov	edx,.c2g
       sar	edx,ROUND
       push	dx
       mov	edx,.c2b
       sar	edx,ROUND
       push	dx
       sar	ebx,ROUND    ; x2
       push	bx
       mov	edx,.c1r
       sar	edx,ROUND
       push	dx
       mov	edx,.c1g
       sar	edx,ROUND
       push	dx
       mov	edx,.c1b
       sar	edx,ROUND
       push	dx
       sar	eax,ROUND
       push	ax	      ; x1
       push	cx	      ; y
       push	.zz2
       push	.zz1
       call	gouraud_line_z

       popad

       mov	edx,.dc13r
       add	.c1r,edx
       mov	edx,.dc13g
       add	.c1g,edx
       mov	edx,.dc13b
       add	.c1b,edx
       mov	edx,.dc23r
       add	.c2r,edx
       mov	edx,.dc23g
       add	.c2g,edx
       mov	edx,.dc23b
       add	.c2b,edx
       mov	edx,.dz13
       add	.zz1,edx
       mov	edx,.dz23
       add	.zz2,edx

       add	eax,.dx13
       add	ebx,.dx23
       inc	cx
       cmp	cx,.y3
       jl	.gt_loop2
   .gt_loop2_end:

       mov	esp,ebp
ret 24
gouraud_line_z:
;----------------- procedure drawing gouraud line
;----------------- with z coordinate interpolation
;----------------- esi - pointer to Z_buffer
;----------------- edi - pointer to screen buffer
;----------------- stack:
.z1  equ dword[ebp+4]	; z coordiunate shifted left CATMULL_SHIFT
.z2  equ dword[ebp+8]
.y   equ word[ebp+12]
.x1  equ ebp+14
.c1b equ ebp+16
.c1g equ ebp+18
.c1r equ ebp+20
.x2  equ ebp+22
.c2b equ ebp+24
.c2g equ ebp+26
.c2r equ ebp+28
.dz   equ dword[ebp-4]
.dc_r equ dword[ebp-8]
.dc_g equ dword[ebp-12]
.dc_b equ dword[ebp-16]
.cr   equ dword[ebp-20]
.cg   equ dword[ebp-24]
.cb   equ dword[ebp-28]
	mov	  ebp,esp

	mov	ax,.y
	or	ax,ax
	jl	.gl_quit
	cmp	ax,SIZE_Y
	jge	.gl_quit

	mov	eax,dword[.x1]
	cmp	ax,word[.x2]
	je	.gl_quit
	jl	@f

	xchg	eax,dword[.x2]
	mov	dword[.x1],eax
	mov	eax,dword[.c1g]
	xchg	eax,dword[.c2g]
	mov	dword[.c1g],eax
	mov	eax,.z1
	xchg	eax,.z2
	mov	.z1,eax
   @@:
	cmp	word[.x1],SIZE_X
	jge	.gl_quit
	cmp	word[.x2],0
	jle	.gl_quit

	mov	eax,.z2
	sub	eax,.z1
	cdq
	mov	bx,word[.x2]	  ; dz = z2-z1/x2-x1
	sub	bx,word[.x1]
	movsx	ebx,bx
	idiv	ebx
	push	eax

	mov	ax,word[.c2r]
	sub	ax,word[.c1r]
	cwde
	shl	eax,ROUND	  ; dc_r = c2r-c1r/x2-x1
	cdq
	idiv	ebx
	push	eax

	mov	ax,word[.c2g]
	sub	ax,word[.c1g]
	cwde
	shl	eax,ROUND
	cdq
	idiv	ebx
	push	eax

	mov	ax,word[.c2b]
	sub	ax,word[.c1b]
	cwde
	shl	eax,ROUND
	cdq
	idiv	ebx
	push	eax

	cmp	word[.x1],0	; clipping on function
	jg	@f
	mov	eax,.dz
	movsx	ebx,word[.x1]
	neg	ebx
	imul	ebx
	add	.z1,eax
	mov	word[.x1],0

	mov	eax,.dc_r
	imul	ebx
	sar	eax,ROUND
	add	word[.c1r],ax

	mov	eax,.dc_g
	imul	ebx
	sar	eax,ROUND
	add	word[.c1g],ax

	mov	eax,.dc_b
	imul	ebx
	sar	eax,ROUND
	add	word[.c1b],ax

      @@:
	cmp	word[.x2],SIZE_X
	jl	@f
	mov	word[.x2],SIZE_X
     @@:
	sub	esp,12	    ; calculate memory begin
	mov	edx,SIZE_X	 ; in buffers
	movzx	eax,.y
	mul	edx
	movzx	edx,word[.x1]
	add	eax,edx
	push	eax
	lea	eax,[eax*3]
	add	edi,eax
	pop	eax
	shl	eax,2
	add	esi,eax

	mov	cx,word[.x2]
	sub	cx,word[.x1]
	movzx	ecx,cx
	mov	ebx,.z1 	 ; ebx - currrent z shl CATMULL_SIFT
	mov	edx,.dz 	 ; edx - delta z
	movzx	eax,word[.c1r]
	shl	eax,ROUND
	mov	.cr,eax
	movzx	eax,word[.c1g]
	shl	eax,ROUND
	mov	.cg,eax
	movzx	eax,word[.c1b]
	shl	eax,ROUND
	mov	.cb,eax
      .ddraw:
	cmp	ebx,dword[esi]	 ; esi - z_buffer
	jge	.skip		 ; edi - Screen buffer
	mov	eax,.cr
	sar	eax,ROUND
	stosb
	mov	eax,.cg
	sar	eax,ROUND
	stosb
	mov	eax,.cb
	sar	eax,ROUND
	stosb
	mov	dword[esi],ebx
	jmp	.no_skip
      .skip:
	add	edi,3
      .no_skip:
	add	esi,4
	add	ebx,edx
	mov	eax,.dc_r
	add	.cr,eax
	mov	eax,.dc_g
	add	.cg,eax
	mov	eax,.dc_b
	add	.cb,eax
	loop	.ddraw

   .gl_quit:
	mov	  esp,ebp
ret 26