gouraud_triangle:
;------------------in - eax - x1 shl 16 + y1 ---------
;---------------------- ebx - x2 shl 16 + y2 ---------
;---------------------- ecx - x3 shl 16 + y3 ---------
;---------------------- edi - pointer to screen buffer
;---------------------- stack : colors----------------
;----------------- procedure don't save registers !!--
.col1r equ ebp+4	     ; each color as word
.col1g equ ebp+6
.col1b equ ebp+8
.col2r equ ebp+10
.col2g equ ebp+12
.col2b equ ebp+14
.col3r equ ebp+16
.col3g equ ebp+18
.col3b equ ebp+20

.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]
.dc12r equ dword[ebp-20]
.dc12g equ [ebp-24]
.dc12b equ dword[ebp-28]
.dx13  equ dword[ebp-32]
.dc13r equ dword[ebp-36]
.dc13g equ [ebp-40]
.dc13b equ dword[ebp-44]
.dx23  equ dword[ebp-48]
.dc23r equ dword[ebp-52]
.dc23g equ [ebp-56]
.dc23b equ dword[ebp-60]

.c1r   equ dword[ebp-64]
.c1g   equ [ebp-68]
.c1b   equ dword[ebp-72]
.c2r   equ dword[ebp-76]
.c2g   equ [ebp-80]
.c2b   equ dword[ebp-84]


       mov ebp,esp
;       sub esp,72

 .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 dx,word[.col1b]
       xchg dx,word[.col2b]
       mov word[.col1b],dx
 .sort1:
       cmp bx,cx
       jle .sort2
       xchg ebx,ecx
       mov edx,dword[.col2r]
       xchg edx,dword[.col3r]
       mov dword[.col2r],edx
       mov dx,word[.col2b]
       xchg dx,word[.col3b]
       mov word[.col2b],dx
       jmp .sort3
 .sort2:
       push eax   ;store triangle coordinates in user friendly variables
       push ebx
       push ecx
    ;   sub esp,72 ; set correctly value of esp

       mov edx,eax    ; check only X triangle coordinate
       or edx,ebx
       or edx,ecx
       test edx,80000000h
       jne .gt_loop2_end
       shr eax,16
       cmp ax,SIZE_X-1
       jg .gt_loop2_end
       shr ebx,16
       cmp bx,SIZE_X-1
       jg .gt_loop2_end
       shr ecx,16
       cmp cx,SIZE_X-1
       jg .gt_loop2_end


       mov bx,.y2	; calc deltas
       sub bx,.y1
       jnz .gt_dx12_make
       xor edx,edx
       mov ecx,4
     @@:
       push edx
       loop @b
     ;  mov .dx12,0
     ;  mov .dc12r,0
     ;  mov .dc12g,0
     ;  mov .dc12b,0
       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[.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
       sub bx,.y1
       jnz .gt_dx13_make
       xor edx,edx
       mov ecx,4
     @@:
       push edx
       loop @b
   ;    mov .dx13,0
   ;    mov .dc13r,0
   ;    mov .dc13g,0
   ;    mov .dc13b,0
       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[.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
       sub bx,.y2
       jnz .gt_dx23_make
       xor edx,edx
       mov ecx,4
     @@:
       push edx
       loop @b
   ;    mov .dx23,0
   ;    mov .dc23r,0
   ;    mov .dc23g,0
   ;    mov .dc23b,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
       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,24
       movsx eax,.x1
       shl eax,ROUND
       mov ebx,eax
       movsx edx,word[.col1r]
       shl edx,ROUND
       mov .c1r,edx
       mov .c2r,edx
       movsx edx,word[.col1g]
       shl edx,ROUND
       mov .c1g,edx
       mov .c2g,edx
       movsx edx,word[.col1b]
       shl edx,ROUND
       mov .c1b,edx
       mov .c2b,edx
       mov cx,.y1
       cmp cx,.y2
       jge .gt_loop1_end
.gt_loop1:
       push eax 		      ; eax - cur x1
       push ebx 		      ; ebx - cur x2
       push cx			      ; cx  - cur y
       push edi
       push ebp

       sar ebx,ROUND
       push bx
       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 eax,ROUND
       push ax
       mov edx,.c1r
       sar edx,ROUND
       push dx
       mov edx,.c1g
       sar edx,ROUND
       push dx
       mov edx,.c1b
       sar edx,ROUND
       push dx
       push cx
       call gouraud_line

       pop ebp
       pop edi
       pop cx
       pop ebx
       pop eax

if Ext >= MMX
       movq mm0,.c1g
       paddd mm0,.dc13g
       movq .c1g,mm0
else
       mov edx,.dc13r
       add .c1r,edx
       mov edx,.dc13g
       add .c1g,edx
end if
       mov edx,.dc13b
       add .c1b,edx
if Ext >= MMX
       movq mm0,.c2g
       paddd mm0,.dc12g
       movq .c2g,mm0
else
       mov edx,.dc12r
       add .c2r,edx
       mov edx,.dc12g
       add .c2g,edx
end if
       mov edx,.dc12b
       add .c2b,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
       shl ebx,ROUND

       movsx edx,word[.col2r]
       shl edx,ROUND
       mov .c2r,edx
       movsx edx,word[.col2g]
       shl edx,ROUND
       mov .c2g,edx
       movsx edx,word[.col2b]
       shl edx,ROUND
       mov .c2b,edx
.gt_loop2:
       push eax 		      ; eax - cur x1
       push ebx 		      ; ebx - cur x2
       push cx
       push edi
       push ebp

       sar ebx,ROUND
       push bx
       mov edx,.c2r
       sar edx,ROUND
       push dx
       mov edx,.c2g
       sar edx,ROUND
       push dx
       mov edx,.c2b
       sar edx,ROUND
       push dx

       sar eax,ROUND
       push ax
       mov edx,.c1r
       sar edx,ROUND
       push dx
       mov edx,.c1g
       sar edx,ROUND
       push dx
       mov edx,.c1b
       sar edx,ROUND
       push dx
       push cx
       call gouraud_line

       pop ebp
       pop edi
       pop cx
       pop ebx
       pop eax

if Ext >= MMX
       movq mm0,.c1g
       paddd mm0,.dc13g
       movq .c1g,mm0
else
       mov edx,.dc13r
       add .c1r,edx
       mov edx,.dc13g
       add .c1g,edx
end if
       mov edx,.dc13b
       add .c1b,edx
if Ext >= MMX
       movq mm0,.c2g
       paddd mm0,.dc23g
       movq .c2g,mm0
else
       mov edx,.dc23r
       add .c2r,edx
       mov edx,.dc23g
       add .c2g,edx
end if
       mov edx,.dc23b
       add .c2b,edx

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

      ; add esp,84
      mov esp,ebp
ret 18
gouraud_line:
;-------------in - edi - pointer to screen buffer
;----------------- stack - another parameters
.y equ word [ebp+4]
.col1b equ ebp+6
.col1g equ ebp+8
.col1r equ ebp+10
.x1    equ [ebp+12]
.col2b equ ebp+14
.col2g equ ebp+16
.col2r equ ebp+18
.x2    equ [ebp+20]
.dc_r equ dword[ebp-4]
.dc_g equ dword[ebp-8]
.dc_b equ dword[ebp-12]
       mov ebp,esp

       mov ax,.y
       or ax,ax
       jl .gl_quit
       cmp ax,SIZE_Y-1
       jg .gl_quit

       mov ax,.x1
       cmp ax,.x2
       je .gl_quit
       jl .gl_ok

if Ext >= MMX
       movq mm0,[.col1b]
       movq mm1,[.col2b]
       movq [.col1b],mm1
       movq [.col2b],mm0
else
       mov eax,[.col1b]
       xchg eax,[.col2b]
       mov  [.col1b],eax
       mov eax,[.col1r]
       xchg eax,[.col2r]
       mov [.col1r],eax
end if
.gl_ok:
  ;     cmp .x1,SIZE_X-1  ;check
  ;     jg .gl_quit
  ;     cmp .x2,SIZE_X-1
  ;     jl @f
  ;     mov .x2,SIZE_X-1
  ;  @@:
  ;     cmp .x1,0
  ;     jg @f
  ;     mov .x1,0
  ;  @@:
  ;     cmp .x2,0
  ;     jl .gl_quit

       movsx ecx,.y
       mov eax,SIZE_X*3
       mul ecx
       movsx ebx,word .x1
       lea ecx,[ebx*2+eax]
       add edi,ecx
       add edi,ebx

       mov ax,word[.col2r]
       sub ax,word[.col1r]
       cwde
       shl eax,ROUND
       cdq
       mov cx,.x2
       sub cx,.x1
       movsx ecx,cx
       idiv ecx
       ;mov .dc_r,eax           ;first delta
       push eax

       mov ax,word[.col2g]
       sub ax,word[.col1g]
       cwde
       shl eax,ROUND
       cdq
       idiv ecx
       ;mov .dc_g,eax
       push eax

       mov ax,word[.col2b]
       sub ax,word[.col1b]
       cwde
       shl eax,ROUND
       cdq
       idiv ecx
      ; mov .dc_b,eax
       push eax

       movsx ebx,word[.col1r]
       shl ebx,ROUND
       movsx edx,word[.col1g]
       shl edx,ROUND
       movsx esi,word[.col1b]
       shl esi,ROUND
.gl_draw:
       mov eax,ebx
       sar eax,ROUND
       stosb
       mov eax,edx
       sar eax,ROUND
       stosb
       mov eax,esi
       sar eax,ROUND
       stosb
       add ebx,.dc_r
       add edx,.dc_g
       add esi,.dc_b
       loop .gl_draw
.gl_quit:
      ; add esp,12
       mov esp,ebp
ret 18
if 0
gouraud_line_SSE:	 ; new
;-------------in - edi - pointer to screen buffer
;----------------- stack - another parameters
.y equ word [ebp+4]
.col1b equ ebp+6
.col1g equ ebp+8
.col1r equ ebp+10
.x1    equ [ebp+12]
.col2b equ ebp+14
.col2g equ ebp+16
.col2r equ ebp+18
.x2    equ [ebp+20]
.dc_r equ dword[ebp-4]
.dc_g equ dword[ebp-8]
.dc_b equ dword[ebp-12]
.lenght equ [ebp-16]
.factor equ [ebp-24]   ;new
       mov ebp,esp

       mov ax,.y
       or ax,ax
       jl .gl_quit
       cmp ax,SIZE_Y-1
       jg .gl_quit

       mov ax,.x1
       cmp ax,.x2
       je .gl_quit
       jl .gl_ok

if Ext >= MMX
       movq mm0,[.col1b]
       movq mm1,[.col2b]
       movq [.col1b],mm1
       movq [.col2b],mm0
else
       mov eax,[.col1b]
       xchg eax,[.col2b]
       mov  [.col1b],eax
       mov eax,[.col1r]
       xchg eax,[.col2r]
       mov [.col1r],eax
end if
.gl_ok:
  ;     cmp .x1,SIZE_X-1  ;check
  ;     jg .gl_quit
  ;     cmp .x2,SIZE_X-1
  ;     jl @f
  ;     mov .x2,SIZE_X-1
  ;  @@:
  ;     cmp .x1,0
  ;     jg @f
  ;     mov .x1,0
  ;  @@:
  ;     cmp .x2,0
  ;     jl .gl_quit

       movsx ecx,.y
       mov eax,SIZE_X*3
       mul ecx
       movsx ebx,word .x1
       lea ecx,[ebx*2+eax]
       add edi,ecx
       add edi,ebx

       mov ax,word[.col2r]
       sub ax,word[.col1r]
       cwde
       shl eax,ROUND
       cdq
       mov cx,.x2
       sub cx,.x1
       movsx ecx,cx
       idiv ecx
       ;mov .dc_r,eax           ;first delta
       push eax

       mov ax,word[.col2g]
       sub ax,word[.col1g]
       cwde
       shl eax,ROUND
       cdq
       idiv ecx
       ;mov .dc_g,eax
       push eax

       mov ax,word[.col2b]
       sub ax,word[.col1b]
       cwde
       shl eax,ROUND
       cdq
       idiv ecx
      ; mov .dc_b,eax
       push eax

       movsx ebx,word[.col1r]
       shl ebx,ROUND
       movsx edx,word[.col1g]
       shl edx,ROUND
       movsx esi,word[.col1b]
       shl esi,ROUND

       push	 ecx	     ; store line lenght
       movd	 mm3,.dc_r
       psrlq	 mm3,16      ; load dr to lowest word of mm3
       pxor	 mm2,mm2     ; clear mm2
       movd	 mm4,.dc_g
       punpcklwd mm3,mm3     ; unpack dr to lower 2 words in in mm3
       psrlq	 mm4,16      ; load dg to lowest word of mm4
       movd	 mm5,.dc_b
       psrlq	 mm5,16      ; load db to lowest word of mm5
       punpcklwd mm4,mm4     ; unpack dg to lower 2 words in in mm3
       lea	 ecx,[factor]
       punpckldq mm3,mm3
       punpcklwd mm5,mm5     ; unpack db to lower 2 words in in mm5
       movq	 mm6,[.col1b]
       xor	 eax,eax
       pinsrw	 mm6,eax,3     ; clear the highest word in mm6
       mov	 eax,010000h
       punpckldq mm4,mm4     ; unpack dg to 4 words in mm4
       mov	 [ecx],eax
       mov	 eax,030002h
       punpckldq mm5,mm5    ; unpack db to 4 words in mm5
       movq	 mm7,mm6    ; load r1r1,g1g1,b1b1 to the first three
			    ; words of mm7
       pxor	 mm1,mm1    ; clear mm1


.gl_draw:
       mov eax,ebx
       sar eax,ROUND
       stosb
       mov eax,edx
       sar eax,ROUND
       stosb
       mov eax,esi
       sar eax,ROUND
       stosb
       add ebx,.dc_r
       add edx,.dc_g
       add esi,.dc_b
       loop .gl_draw
.gl_quit:
      ; add esp,12
       mov esp,ebp
ret 18
end if