CATMULL_SHIFT  equ 8
ROUND equ 8
;NON=0
;MMX=1
;Ext=MMX
;TEX_SIZE=0x3fff
;SIZE_X equ 512
;SIZE_Y equ 512
;ROUND = 8
;TEX_SHIFT equ 6

; procedure drawing textured triangle with Gouraud shading
; Z-buffer alghoritm included, Z coord interpolation ----
; I set the color by this way -- (col1 * col2)/256 ------
;------------------in - eax - x1 shl 16 + y1 ------------
;---------------------- ebx - x2 shl 16 + y2 ------------
;---------------------- ecx - x3 shl 16 + y3 ------------
;---------------------- esi - pointer to Z-buffer--------
;---------------------- edx - pointer to texture---------
;---------------------- Z-buffer filled with dd variables
;---------------------- shifted CATMULL_SHIFT------------
;---------------------- edi - pointer to screen buffer---
;---------------------- stack : colors-------------------



tex_plus_grd_triangle:
; parameters :
   .tex_y3  equ [ebp+38]   ; 36 bytes through stack
   .tex_x3  equ [ebp+36]
   .tex_y2  equ [ebp+34]
   .tex_x2  equ [ebp+32]
   .tex_y1  equ [ebp+30]
   .tex_x1  equ [ebp+28]

   .z3	    equ [ebp+26]
   .col3b   equ [ebp+24]
   .col3g   equ [ebp+22]
   .col3r   equ [ebp+20]

   .z2	    equ [ebp+18]
   .col2b   equ [ebp+16]
   .col2g   equ [ebp+14]
   .col2r   equ [ebp+12]

   .z1	    equ [ebp+10]
   .col1b   equ [ebp+8]
   .col1g   equ [ebp+6]
   .col1r   equ [ebp+4]

; local variables:

   .tex_ptr   equ dword[ebp-4]
   .z_ptr     equ dword[ebp-8]
   .scr_buff  equ dword[ebp-12]

   .x1	      equ  word[ebp-14] ;dw ? ;equ word[ebp-10]
   .y1	      equ  word[ebp-16] ;dw ? ;equ word[ebp-12]
   .x2	      equ  word[ebp-18] ;dw ? ;equ word[ebp-14]
   .y2	      equ  word[ebp-20] ;dw ? ;equ word[ebp-16]
   .x3	      equ  word[ebp-22] ;dw ? ;equ word[ebp-18]
   .y3	      equ  word[ebp-24] ;dw ? ;equ word[ebp-20]

   .dx12      equ  dword[ebp-28] ;dd ?
   .tex_dx12  equ  dword[ebp-32] ;dd ?
   .tex_dy12  equ	[ebp-36] ;dd ?
   .dz12      equ  dword[ebp-40] ;dd ?
   .dc12r     equ	[ebp-44] ;dd ?
   .dc12g     equ  dword[ebp-48] ;dd ?
   .dc12b     equ	[ebp-52] ;dd ?

   .dx23      equ  dword[ebp-56] ;dd ?
   .tex_dx23  equ  dword[ebp-60] ;dd ?
   .tex_dy23  equ	[ebp-64] ;dd ?
   .dz23      equ  dword[ebp-68] ;dd ?
   .dc23r     equ	[ebp-72] ;dd ?
   .dc23g     equ  dword[ebp-76] ;dd ?
   .dc23b     equ	[ebp-80] ;dword[ebp-8]dd ?

   .dx13      equ  dword[ebp-84] ;dd ?
   .tex_dx13  equ  dword[ebp-88] ;dd ?
   .tex_dy13  equ	[ebp-92] ;dd ?
   .dz13      equ  dword[ebp-96] ;dd ?
   .dc13r     equ	[ebp-100] ;dd ?
   .dc13g     equ  dword[ebp-104] ;dd ?
   .dc13b     equ	[ebp-108] ;dd ?

   .scan_x1   equ  dword[ebp-112] ;dd ?
   .scan_y1   equ	[ebp-116] ;dd ?
   .zz1       equ  dword[ebp-120] ;dw ?
   .cur1r     equ	[ebp-124] ;dw ?
   .cur1g     equ  dword[ebp-128] ;dw ?
   .cur1b     equ	[ebp-132] ;dw ?

   .scan_x2   equ  dword[ebp-136] ;dd ?
   .scan_y2   equ	[ebp-140] ;dd ?
   .zz2       equ  dword[ebp-144] ;dw ?
   .cur2r     equ	[ebp-148] ;dw ?
   .cur2g     equ  dword[ebp-152] ;dw ?
   .cur2b     equ	[ebp-156] ;dw ?


       mov    ebp,esp

   ;    mov     .tex_ptr,edx
   ;    mov     .z_ptr,esi
   ;    mov     .scr_buff,edi
	 push	 edx esi edi
;         push    esi
;         push    edi
	 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	  .loop2_end

   .sort3:
       cmp     ax,bx
       jle     .sort1
       xchg    eax,ebx
if Ext>=MMX
       movq    mm0, .col1r	 ; exchange r, g, b, z
       movq    mm1, .col2r
       movq    .col1r ,mm1
       movq    .col2r ,mm0
else
       mov     edx,dword .col1r   ; exchange both r and g
       xchg    edx,dword .col2r
       mov     dword .col1r ,edx

       mov     edx,dword .col1b   ; b and z
       xchg    edx,dword .col2b
       mov     dword .col1b ,edx
end if

       mov     edx,dword .tex_x1
       xchg    edx,dword .tex_x2
       mov     dword .tex_x1 ,edx

 .sort1:
       cmp	bx,cx
       jle	.sort2
       xchg    ebx,ecx

if Ext>=MMX
       movq    mm0, .col2r	 ; exchange r, g, b, z
       movq    mm1, .col3r
       movq    .col3r ,mm0
       movq    .col2r ,mm1
else

       mov     edx,dword .col2r  ; r, g
       xchg    edx,dword .col3r
       mov     dword .col2r,edx

       mov     edx,dword .col2b  ; b, z
       xchg    edx,dword .col3b
       mov     dword .col2b,edx
end if

       mov     edx,dword .tex_x2
       xchg    edx,dword .tex_x3
       mov     dword .tex_x2,edx

       jmp .sort3

 .sort2:

       push	eax ebx ecx	    ; store in variables
  ;     push     ebx
  ;     push     ecx

;****************** delta computng zone **************
;+++++++++ first zone
       mov	bx,.y2	     ; calc delta12
       sub	bx,.y1
       jnz	.dx12_make
       mov	ecx,7
     @@:
       push	dword 0
       loop	@b
       jmp	.dx12_done
  .dx12_make:


       mov	ax,.x2
       sub	ax,.x1
       cwde
       movsx	ebx,bx
       shl	eax,ROUND
       cdq
       idiv	ebx
 ;      mov      .dx12,eax
       push	 eax

if  0  ; Ext=SSE
       movd	 mm0,.col1r    ; 2 words  r, g
       pxor	 mm1,mm1
       punpcklwd mm0,mm1
       cvtpi2ps  xmm0,mm0
       movlhps	 xmm0,xmm0
       movd	 mm0,.col1g    ; 2 words  b, z
       punpcklwd mm0,mm1
       cvtpi2ps  xmm0,mm0
       ; xmm0=four float double words
       divss	 xmm0,.pack3
       ;convert and insert mm0 to lower xmm1     ..
end if

       mov	ax,word .tex_x2
       sub	ax,word .tex_x1
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
;       mov      .tex_dx12r,eax
       push	  eax

       mov	  ax,word .tex_y2
       sub	  ax,word .tex_y1
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
;       mov      .tex_dx12,eax
       push	eax

       mov	ax,word .z2
       sub	ax,word .z1
       cwde
       shl	eax,CATMULL_SHIFT
       cdq
       idiv	ebx
 ;      mov      .dz12,eax
       push	eax	  ; .dza12

       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

;+++++++++++++++++ second zone +++++++++++++
   .dx12_done:

       mov	bx,.y3	     ; calc delta23
       sub	bx,.y2
       jnz	.dx23_make
       mov	ecx,7
    @@:
       push	dword 0
       loop	@b
       jmp	.dx23_done

  .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 .tex_x3
       sub	ax,word .tex_x2
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
;       mov      .tex_dx23,eax
       push	  eax

       mov	  ax,word .tex_y3
       sub	  ax,word .tex_y2
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
;       mov      .tex_dy23,eax
       push	eax

       mov	ax,word .z3
       sub	ax,word .z2
       cwde				   ;
       shl	eax,CATMULL_SHIFT	   ;  2222222
       cdq				   ;  2     2
       idiv	ebx			   ;        2
;       mov      .dz23,eax                 ;       2
       push	eax	  ; .dza12         ;      2
					   ;     2
       mov	ax,word .col3r		   ;    2
       sub	ax,word .col2r		   ;   2222222
       cwde				   ;  second delta
       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

   .dx23_done:
;++++++++++++++++++third zone++++++++++++++++++++++++
       mov	bx,.y3	     ; calc delta13
       sub	bx,.y1
       jnz	.dx13_make
       mov	ecx,7
     @@:
       push	dword 0
       loop	@b
       jmp	.dx13_done
  .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 .tex_x3 	   ; triangle b
       sub	ax,word .tex_x1
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
;       mov      .tex_dx13r,eax
       push	  eax

       mov	  ax,word .tex_y3
       sub	  ax,word .tex_y1
       cwde
       shl	eax,ROUND
       cdq
       idiv	ebx
;       mov      .tex_dy13,eax
       push	eax

       mov	ax,word .z3
       sub	ax,word .z1	       ;    333333333
       cwde			       ;   3        3
       shl	eax,CATMULL_SHIFT      ;            3
       cdq			       ;            3
       idiv	ebx		       ;            3
;       mov      .dz13,eax             ;            3
       push	eax	  ; .dza12     ;            3
				       ;            3
       mov	ax,word .col3r	       ;    3333333333
       sub	ax,word .col1r	       ;            3
       cwde			       ;            3
       shl	eax,ROUND	       ;            3
       cdq			       ;            3
       idiv	ebx		       ;            3
  ;    mov      .dc13r,eax             ;    3       3
       push	  eax		      ;     33333333

       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

   .dx13_done:

; <<<<<<<  ::delta zone end+++++++++++++++++++++ >>>>>>>>
       sub	esp,55	 ;(12*4)

       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	edi,word .col1r
       shl	edi,ROUND
       mov	.cur1r,edi
       mov	.cur2r,edi
       movzx	esi,word .col1g
       shl	esi,ROUND
       mov	.cur1g,esi
       mov	.cur2g,esi
       movzx	edx,word .col1b
       shl	edx,ROUND
       mov	.cur1b,edx
       mov	.cur2b,edx

       movzx	edi,word .tex_x1
       shl	edi,ROUND
       mov	.scan_x1,edi
       mov	.scan_x2,edi
       movzx	edx,word .tex_y1
       shl	edx,ROUND
       mov	.scan_y1,edx
       mov	.scan_y2,edx

       mov	cx,.y1
       cmp	cx,.y2
       jge	.loop1_end
    .loop_1:
    ;   push     eax ebx ebp
       pushad

       push	.tex_ptr
       push	.scr_buff
       push	.z_ptr
       push	cx

       push	.zz2

       push	.scan_x2
       push	dword .scan_y2
       push	dword .cur2r
       push	.cur2g
       push	dword .cur2b

       push	.zz1

       push	.scan_x1
       push	dword .scan_y1
       push	dword .cur1r
       push	.cur1g
       push	dword .cur1b

       sar	eax,ROUND
       sar	ebx,ROUND
       call	horizontal_tex_grd_line

      ; pop      ebp ebx eax
       popad

if (Ext = MMX)|(Ext=SSE)
       movq	mm0,.cur1b
       movq	mm1,.cur1r
       movq	mm2,.scan_y1
       movq	mm3,.cur2b
       movq	mm4,.cur2r
       movq	mm5,.scan_y2
       paddd	mm0,.dc13b
       paddd	mm1,.dc13r
       paddd	mm2,.tex_dy13
       paddd	mm3,.dc12b
       paddd	mm4,.dc12r
       paddd	mm5,.tex_dy12
       movq	.cur1b,mm0
       movq	.cur1r,mm1
       movq	.scan_y1,mm2
       movq	.cur2b,mm3
       movq	.cur2r,mm4
       movq	.scan_y2,mm5
end if
if Ext >= SSE2
       movups	xmm0,.cur1b
       movups	xmm1,.dc13b
       movups	xmm2,.cur2b
       movups	xmm3,.dc12b
       movq	mm2,.scan_y1
       movq	mm5,.scan_y2
       paddd	xmm0,xmm1
       paddd	xmm2,xmm3
       paddd	mm2,.tex_dy13
       paddd	mm5,.tex_dy12
       movq	.scan_y1,mm2
       movq	.scan_y2,mm5
       movups	.cur1b,xmm0
       movups	.cur2b,xmm2
end if

if Ext = NON
       mov	edx,.dc13b
       add	.cur1b,edx
       mov	esi,.dc13g
       add	.cur1g,esi
       mov	edi,.dc13r
       add	.cur1r,edi
       mov	edx,.dz13
       add	.zz1,edx
       mov	edx,.tex_dx13
       add	.scan_x1,edx
       mov	esi,.tex_dy13
       add	.scan_y1,esi

       mov	edi,.dc12b
       add	.cur2b,edi
       mov	esi,.dc12g
       add	.cur2g,esi
       mov	edx,.dc12r
       add	.cur2r,edx
       mov	edi,.tex_dx12
       add	.scan_x2,edi
       mov	esi,.tex_dy12
       add	.scan_y2,esi
       mov	edx,.dz12
       add	.zz2,edx
end if
       add	eax,.dx13
       add	ebx,.dx12
       inc	cx
       cmp	cx,.y2
       jl      .loop_1
 .loop1_end:
       movzx	ecx,.y2
       cmp	cx,.y3
       jge	.loop2_end

       movsx	ebx,.x2 		   ; eax - cur x1
       shl	ebx,ROUND		   ; ebx - cur x2

       movsx	edx,word .z2
       shl	edx,CATMULL_SHIFT
;       mov      .zz1,edx
       mov	.zz2,edx

       movzx	edi,word .col2r
       shl	edi,ROUND
   ;    mov      .cur1r,edi
       mov	.cur2r,edi
       movzx	esi,word .col2g
       shl	esi,ROUND
   ;    mov      .cur1g,esi
       mov	.cur2g,esi
       movzx	edx,word .col2b
       shl	edx,ROUND
   ;    mov      .cur1b,edx
       mov	.cur2b,edx

       movzx	edi,word .tex_x2
       shl	edi,ROUND
 ;      mov      .scan_x1,edi
       mov	.scan_x2,edi
       movzx	edx,word .tex_y2
       shl	edx,ROUND
 ;      mov      .scan_y1,edx
       mov	.scan_y2,edx

  .loop_2:
       pushad

       push	.tex_ptr
       push	.scr_buff
       push	.z_ptr
       push	cx

       push	.zz2

       push	.scan_x2
       push	dword .scan_y2
       push	dword .cur2r
       push	.cur2g
       push	dword .cur2b

       push	.zz1

       push	.scan_x1
       push	dword .scan_y1
       push	dword .cur1r
       push	.cur1g
       push	dword .cur1b

       sar	eax,ROUND
       sar	ebx,ROUND
       call	horizontal_tex_grd_line

       popad

if (Ext = MMX)|(Ext=SSE)
       movq	mm0,.cur1b
       movq	mm1,.cur1r
       movq	mm2,.scan_y1
       movq	mm3,.cur2b
       movq	mm4,.cur2r
       movq	mm5,.scan_y2
       paddd	mm0,.dc13b
       paddd	mm1,.dc13r
       paddd	mm2,.tex_dy13
       paddd	mm3,.dc23b
       paddd	mm4,.dc23r
       paddd	mm5,.tex_dy23
       movq	.cur1b,mm0
       movq	.cur1r,mm1
       movq	.scan_y1,mm2
       movq	.cur2b,mm3
       movq	.cur2r,mm4
       movq	.scan_y2,mm5
end if
if Ext >= SSE2
       movups	xmm0,.cur1b
       movups	xmm1,.dc13b
       movups	xmm2,.cur2b
       movups	xmm3,.dc23b
       movq	mm2,.scan_y1
       movq	mm5,.scan_y2
       paddd	xmm0,xmm1
       paddd	xmm2,xmm3
       paddd	mm2,.tex_dy13
       paddd	mm5,.tex_dy23
       movq	.scan_y1,mm2
       movq	.scan_y2,mm5
       movups	.cur1b,xmm0
       movups	.cur2b,xmm2
end if
if Ext = NON
       mov	edx,.dc13b
       add	.cur1b,edx
       mov	esi,.dc13g
       add	.cur1g,esi
       mov	edi,.dc13r
       add	.cur1r,edi
       mov	edx,.tex_dx13
       add	.scan_x1,edx
       mov	esi,.tex_dy13
       add	.scan_y1,esi
       mov	edx,.dz13
       add	.zz1,edx

       mov	edi,.dc23b
       add	.cur2b,edi
       mov	esi,.dc23g
       add	.cur2g,esi
       mov	edx,.dc23r
       add	.cur2r,edx
       mov	edi,.tex_dx23
       add	.scan_x2,edi
       mov	esi,.tex_dy23
       add	.scan_y2,esi
       mov	edx,.dz23
       add	.zz2,edx
end if
       add	eax,.dx13
       add	ebx,.dx23
       inc	cx
       cmp	cx,.y3
       jl	.loop_2

.loop2_end:
       mov	esp,ebp
ret 36
horizontal_tex_grd_line:
;in:
; eax : x1, ebx : x2

.tex_ptr  equ [ebp+62]
.screen   equ [ebp+58]
.z_buffer equ [ebp+54]
.y	  equ [ebp+52]

.z2	equ [ebp+48]
.tex_x2 equ [ebp+44]
.tex_y2 equ [ebp+40]
.r2	equ [ebp+36]
.g2	equ [ebp+32]
.b2	equ [ebp+28]

.z1	equ [ebp+24]
.tex_x1 equ [ebp+20]
.tex_y1 equ [ebp+16]
.r1	equ [ebp+12]
.g1	equ [ebp+8]
.b1	equ [ebp+4]

.x1 equ  word[ebp-2]
.x2 equ  word[ebp-4]
.dz equ dword[ebp-8]
.db equ dword[ebp-12]
.dg equ dword[ebp-16]
.dr equ dword[ebp-20]
.dtex_x equ dword[ebp-24]
.dtex_y equ dword[ebp-28]

.c_ty equ [ebp-32]
.c_tx equ [ebp-36]
.cb  equ  [ebp-40]
.cg  equ  [ebp-44]
.cr  equ  [ebp-48]
.t_col equ [ebp-52]

.dtex_yM equ qword[ebp-28]
.drM equ qword[ebp-20]
.dbM equ qword[ebp-12]

	mov	ebp,esp
  ;      sub     esp,30

	mov	cx,word .y
	or	cx,cx
	jl	.quit_l

	cmp	cx,SIZE_Y
	jge	.quit_l

	cmp	ax,bx
	je	.quit_l
	jl	@f

	xchg	eax,ebx

if Ext=NON
	mov	ecx,dword .r1
	xchg	ecx, .r2
	mov	dword .r1, ecx

	mov	ecx,dword .g1
	xchg	ecx, .g2
	mov	dword .g1, ecx

	mov	ecx,dword .b1
	xchg	ecx, .b2
	mov	dword .b1, ecx

	mov	ecx,dword .tex_x1
	xchg	ecx, .tex_x2
	mov	dword .tex_x1, ecx

	mov	ecx,dword .tex_y1
	xchg	ecx, .tex_y2
	mov	dword .tex_y1, ecx

	mov	ecx,dword .z1
	xchg	ecx, .z2
	mov	dword .z1, ecx
end if
if (Ext=MMX)
	movq	mm0,.b1        ; b, g
	movq	mm1,.b2
	movq	.b1, mm1
	movq	.b2, mm0
	movq	mm2,.r1        ; r, y
	movq	mm3,.r2
	movq	.r1,mm3
	movq	.r2,mm2
	movq	mm4,.tex_x1    ; x, z
	movq	mm5,.tex_x2
	movq	.tex_x1,mm5
	movq	.tex_x2,mm4

end if
if Ext>=SSE
       movups  xmm0,.b1
       movups  xmm1,.b2
       movups  .b1,xmm1
       movups  .b2,xmm0
       movq    mm4,.tex_x1    ; x, z
       movq    mm5,.tex_x2
       movq    .tex_x1,mm5
       movq    .tex_x2,mm4
end if

    @@:
	or	bx,bx
	jle	.quit_l
	cmp	ax,SIZE_X
	jge	.quit_l

	push	ax
	push	bx

	mov	eax,.z2 	   ; delta zone************
	sub	eax,.z1
	cdq
	mov	bx,.x2
	sub	bx,.x1
	movsx	ebx,bx
	idiv	ebx
	push	eax  ; .dz

	mov	eax,.b2
	sub	eax,.b1
	cdq
	idiv	ebx
	push	eax  ; .db

	mov	eax,.g2
	sub	eax,.g1
	cdq
	idiv	ebx
	push	eax  ; .dg

	mov	eax,.r2
	sub	eax,.r1
	cdq
	idiv	ebx
	push	eax  ; .dr

	mov	eax,.tex_x2
	sub	eax,.tex_x1
	cdq
	idiv	ebx
	push	eax  ; .dtex_x

	mov	eax,.tex_y2
	sub	eax,.tex_y1
	cdq
	idiv	ebx
	push	eax  ; .dtey_x

	cmp	.x1,0
	jg	@f

	mov	eax,.dz     ; clipping
	movsx	ebx,.x1
	neg	ebx
	imul	ebx
	add	.z1,eax
	mov	.x1,0

	mov    eax,.dr
	imul   ebx
	add    .r1,eax
;if  Ext=NON
	mov    eax,.dg
	imul   ebx
	add    .g1,eax

	mov    eax,.db
	imul   ebx
	add    .b1,eax

	mov    eax,.dtex_x
	imul   ebx
	add    .tex_x1,eax

	mov    eax,.dtex_y
	imul   ebx
	add    .tex_y1,eax
   @@:
	mov	  edx,SIZE_X
	cmp	  .x2,dx
	jl	  @f
	mov	  .x2,dx
    @@:
; calc line addres begin in screen and Z buffer
	movsx	  eax,word .y
	mul	  edx
	movsx	  edx,.x1
	add	  eax,edx

	mov	  esi,eax
	shl	  esi,2
	add	  esi,.z_buffer

	lea	  eax,[eax*3]
	mov	  edi,.screen
	add	  edi,eax

	mov	  cx,.x2
	sub	  cx,.x1
	movzx	  ecx,cx

; init current variables
	push	  dword .tex_y1
;if  Ext=NON
	push	  dword .tex_x1

	push	  dword .b1
	push	  dword .g1
	push	  dword .r1

if Ext>=MMX
	movq	  mm4,.cr  ; lo -> r,g
	movq	  mm6,.cb  ; hi -> b, tex_x
	pxor	  mm0,mm0
end if
	mov	  ebx,.z1
      .ddraw:
	cmp	  ebx,dword[esi]
	jge	  @f
	mov	  eax,.c_ty
;  if ROUND<TEX_SHIFT
;        shl        eax,TEX_SHIFT-ROUND
;  end if
;  if ROUND>TEX_SHIFT
;        shr        eax,ROUND-TEX_SHIFT
;  end if
	shr	  eax,ROUND
	shl	  Eax,TEX_SHIFT
	mov	  edx,.c_tx   ; calc texture pixel mem addres
	shr	  edx,ROUND
	add	  eax,edx
	and	  eax,TEXTURE_SIZE   ; cutting
	lea	  eax,[3*eax]
	add	  eax,.tex_ptr
	mov	  dword[esi],ebx
if    Ext = NON
	mov	  eax,dword[eax]
 ;      mov        .tex_col,eax
	push	  ax
	shl	  eax,8
	pop	  ax
	mov	  edx,.cr
	sar	  edx,ROUND
	mul	  dl	     ; al*dl
	shr	  ax,8
	stosb
	ror	  eax,16
	push	  ax
	mov	  edx,.cg
	sar	  edx,ROUND
	mul	  dl
	shr	  ax,8
	stosb
	pop	  ax
	shr	  ax,8
	mov	  edx,.cb
	sar	  edx,ROUND
	mul	  dl
	shr	  ax,8
	stosb
	jmp	  .no_skip
else
	movd	  mm1,[eax]
	punpcklbw mm1,mm0
	movq	  mm3,mm4  ;.cr     ; lo -> r,g
	movq	  mm5,mm6  ;.cb     ; lo -> b,tex_x
	psrld	  mm3,ROUND  ;
	psrld	  mm5,ROUND  ;
	packssdw  mm3,mm5
	pmullw	  mm1,mm3
	psrlw	  mm1,8
	packuswb  mm1,mm0
	movd	  [edi],mm1
end if
       mov	  dword[esi],ebx
if Ext = NON
       jmp	  .no_skip
end if
     @@:
       add	  edi,3
     .no_skip:
       add	  esi,4
       add	  ebx,.dz

       mov	  eax,.dtex_x
       add	  .c_tx, eax
       mov	  edx,.dtex_y
       add	  .c_ty, edx
if Ext=NON
       mov	  eax,.dr
       add	  .cr,eax
       mov	  edx,.dg
       add	  .cg,edx
       mov	  eax,.db
       add	  .cb,eax

else
	paddd	   mm4,.drM
	paddd	   mm6,.dbM
;;        paddd      mm7,.dtex_y      ; mm4 - b, g
;;        movq       .c_tx,mm7
				    ; mm6 - r, x
end if				    ; mm7 - y, x

       dec	ecx
       jnz	.ddraw

  .quit_l:

	mov	esp,ebp
ret 42+20  ; horizontal line