;.586
;.8087
;
;	Assembly scandraws - designed for Pentiums/Pentium Pros but should work ok
;   on 486s and strange hybrid processors. 
;
;	(C) Kevin Lea 12:03:17 96/12/05
;
;	Please excuse the mess, I haven't tidied up yet. Only the inner loops are
;	well coded, since these take far more runtime than initialisation routines.
;


SOURCE_SBITSV	EQU	16
SOURCE_SBITSU	EQU	7

_DATA	SEGMENT DWORD PUBLIC 'DATA'
	
	EXTRN _SCASM_Lighting:DWORD
	EXTRN _SCASM_Destination:DWORD    
	EXTRN _SCASM_Bitmap:DWORD          
	EXTRN _SCASM_StartU:DWORD
	EXTRN _SCASM_StartV:DWORD
	EXTRN _SCASM_StartI:DWORD
	EXTRN _SCASM_DeltaU:DWORD
	EXTRN _SCASM_DeltaV:DWORD
	EXTRN _SCASM_DeltaI:DWORD
	EXTRN _SCASM_ScanLength:DWORD
	EXTRN _SCASM_ShadingTableSize:DWORD
	EXTRN _SCASM_TextureDeltaScan:DWORD
; 	EXTRN _TLT:BYTE PTR

if 0
	EXTRN _sine:DWORD         ;
	EXTRN _cosine:DWORD       ; these 2 in 3D engine already
	EXTRN _MTRB_Bitmap:DWORD
	EXTRN _MTRB_Destination:DWORD
	EXTRN _MTRB_ScanOffset:DWORD
	EXTRN _MTRB_Angle:DWORD;
	EXTRN _MTRB_InvScale:DWORD;
	EXTRN _MTRB_ScreenHeight:DWORD; equ 48
	EXTRN _MTRB_ScreenWidth:DWORD; equ (49*2+1)
	EXTRN _MTRB_ScreenCentreX:DWORD; equ (MTRB_ScreenWidth/2+1)
	EXTRN _MTRB_ScreenCentreY:DWORD; equ MTRB_ScreenHeight
	EXTRN _MTRB_CentreU:DWORD
	EXTRN _MTRB_CentreV:DWORD
endif

	align


	FixedScale dd 65536.0
	FixedScale8 dd 8192.0 ; 2^16 / 8
	One dd 1.0
	FloatTemp dd ?
    FPUCW  word	?
    OldFPUCW  word ?

	DeltaUFrac dd ?
	DeltaVFrac dd ?
	DeltaIFrac dd ?
	Wholesections dd ?
	PixelsRemaining dd ?
	UVintVfracStepVCarry dd ?
	UVintVfracStepVNoCarry dd ?
	UVintVfracStep equ UVintVfracStepVNoCarry
	IintWithCarry dd ?
	IintNoCarry dd ?
	IintStep equ IintNoCarry

	StackStore dd ?

	ShadeTable equ _TextureLightingTable



	aspectAdjust dd (6 SHL 16) / 5
	startingU  	dd 0
 	startingV 	dd 0
	dUCol		dd 0
	dVCol 		dd 0
	dURow  		dd 0
	dVRow  		dd 0
	rowCount  	dd 0





_DATA	ENDS

_TEXT	SEGMENT BYTE PUBLIC 'CODE'
       	ASSUME	cs:_TEXT, ds:_DATA

.586

if 0
align
PUBLIC _ScanDraw_GouraudScan
PUBLIC ScanDraw_GouraudScan_
ScanDraw_GouraudScan_:
_ScanDraw_GouraudScan:

; calculate horizontal deltas
	pushad
 ;   mov 	[StackStore],esp
	
	mov     eax,_SCASM_ScanLength       
    mov		ebp,eax
    
  	and		eax,7
    shr     ebp,3                       
    
	mov		[PixelsRemaining],eax
    mov     [Wholesections],ebp          ; store widths


    ; setup initial coordinates
    mov     ebx,_SCASM_DeltaI           ; get i 16.16 step
    mov     eax,ebx                     ; copy it
    sar     eax,16                      ; get i int step
    shl     ebx,16                      ; get i frac step
    imul    eax,_SCASM_ShadingTableSize
    mov     IintNoCarry,eax				; save whole step in non-i-carry slot
    add     eax,_SCASM_ShadingTableSize      	; calculate whole step + i carry
    mov     IintWithCarry,eax  			; save in i-carry slot

	mov		esi,_SCASM_StartI
	mov		edx,esi
	sar		esi,16
	shl		edx,16
	imul	esi,_SCASM_ShadingTableSize
	add		esi,_SCASM_Lighting

	xor eax,eax
	mov	edi,_SCASM_Destination
	
	test ebp,ebp
	
	jz GS_EndPixels
if 1				 
GS_ScanLoop:
    ; 8 pixel span code
    ; edi = dest dib bits at current pixel
    ; esi = lighting pointer
    ; edx = i fraction 0.32
    ; ebp = carry scratch


;   mov     al,[esi]
;   add		edx,DeltaIFrac
;	sbb		ebp,ebp
;	add 	esi,[4*ebp + IintStep]
;	mov     [edi],al
	
    mov     al,[esi]				;get colour to draw
	
	add		edx,ebx			;increase intensity
	sbb		ebp,ebp					;check for overflow
	
	add 	esi,[4*ebp + IintStep]	;add to esi required change
	add		edx,ebx			;increase intensity
	
	sbb		ebp,ebp					;check for overflow
	mov     [edi+0],al				;draw out pixel
	
	mov     al,[esi]				
	
	add 	esi,[4*ebp + IintStep]
	add		edx,ebx

	sbb		ebp,ebp
	mov     [edi+1],al

	mov     al,[esi]				
	
	add 	esi,[4*ebp + IintStep]
	add		edx,ebx

	sbb		ebp,ebp
	mov     [edi+2],al

	mov     al,[esi]				
	
	add 	esi,[4*ebp + IintStep]
	add		edx,ebx

	sbb		ebp,ebp
	mov     [edi+3],al

	mov     al,[esi]				
	
	add 	esi,[4*ebp + IintStep]
	add		edx,ebx

	sbb		ebp,ebp
	mov     [edi+4],al
	
	mov     al,[esi]				
	
	add 	esi,[4*ebp + IintStep]
	add		edx,ebx

	sbb		ebp,ebp
	mov     [edi+5],al

	mov     al,[esi]				
	
	add 	esi,[4*ebp + IintStep]
	add		edx,ebx

	sbb		ebp,ebp
	mov     [edi+6],al

	mov     al,[esi]				
	
	add 	esi,[4*ebp + IintStep]
	mov     [edi+7],al


	lea edi,[edi+8]
    dec     Wholesections              ; decrement span count

    jnz     GS_ScanLoop                    ; loop back
endif   	

	mov		eax,[PixelsRemaining]
	test	eax,eax
	jz 		GS_finish 
GS_EndPixels:

    mov     al,[esi]          ; get texture pixel  
	
	lea 	edi,[edi+1]

   	add		edx,ebx
	sbb		ebp,ebp
	mov 	[edi-1],al
	
	add 	esi,[4*ebp + IintStep]
	dec		[PixelsRemaining]
	
	jnz		GS_EndPixels
GS_finish:			   
;    mov esp, [StackStore]
	popad
	ret
endif

if 1
align
PUBLIC _ScanDraw_GouraudScan
PUBLIC ScanDraw_GouraudScan_
ScanDraw_GouraudScan_:
_ScanDraw_GouraudScan:

; calculate horizontal deltas
	pushad
    mov 	[StackStore],esp
	
	mov     eax,_SCASM_ScanLength       
    mov		ecx,eax
    
 ;  	and		ecx,7
    shr     eax,3                       
    
	mov		[PixelsRemaining],ecx
    mov     [Wholesections],eax          ; store widths


    ; setup initial coordinates
    mov     esp,_SCASM_DeltaI           ; get i 16.16 step
;    sar     esp,8                      ; get i frac step

	mov		ebx,_SCASM_StartI
;	sar		ebx,8
	mov		edx,ebx
	sar		edx,8
	and		edx,0xff00h

	mov		esi,_SCASM_Lighting

	mov		edi,_SCASM_Destination
	add		edi,ecx
  ;	test	eax,eax
	neg 	ecx
	sub eax,eax	
	jz GS_EndPixels
if 1				 
	mov     ecx,eax
GS_ScanLoop:


	mov 	al,[esi+edx]
	mov		edx,ebx

	add		ebx,esp
	and		edx,0xff00h
	
	mov		[edi+0],al
	nop

	lea 	edi,[edi+8]
    dec     ecx              ; decrement span count

    jnz     GS_ScanLoop                    ; loop back
endif   	

	mov		ecx,[PixelsRemaining]
	test	ecx,ecx
	jz 		GS_finish 
GS_EndPixels:



	mov 	al,[esi+edx]
	mov		edx,ebx

	sar		edx,8
	add		ebx,esp
	
	and		edx,0xff00h
	mov		[edi+ecx],al
	
	inc		ecx
	jnz		GS_EndPixels
GS_finish:			   
    mov esp, [StackStore]
	popad
	ret
endif

align
; Drawing a 2D polygon which has DeltaV=0 and is transparent
PUBLIC _ScanDraw2D_VAlignedTransparent
PUBLIC ScanDraw2D_VAlignedTransparent_
_ScanDraw2D_VAlignedTransparent:
ScanDraw2D_VAlignedTransparent_:

	pushad
    mov [StackStore],esp
	mov     edx,_SCASM_ScanLength       

    mov     esi,_SCASM_StartU           ; get u 16.16 fixedpoint coordinate
    mov     esp,esi                     ; copy it
    sar     esi,16                      ; get integer part
    shl     esp,16                      ; get fractional part

    mov     eax,_SCASM_StartV           ; get v 16.16 fixedpoint coordinate
    sar     eax,16                      ; get integer part
    imul    eax,_SCASM_TextureDeltaScan ; calc texture scanline address
    add     esi,eax                     ; calc texture offset
    add     esi,_SCASM_Bitmap          ; calc address

	mov		edi,_SCASM_Destination
	mov     ebx,_SCASM_DeltaU                ; get u 16.16 step
    mov     ecx,ebx                     ; copy it
    sar     ebx,16                      ; get u int step
    shl     ecx,16                      ; get u frac step

	;	ebx		u int delta
	;	ecx		u frac delta
	;	esp		u frac total
	;	edi 	dest
	;	esi 	source
	;   edx		pixels to draw
VAT_ScanLoop:
    mov     al,[esi]                    ; get texture pixel 0
	add		esp,ecx
	
	adc		esi,ebx
	inc		edi

	test 	al,al
	jz 		VAT_SkipPixel

   	mov 	[edi-1],al          
 	VAT_SkipPixel:
	
	dec     edx              ; decrement span count
    jnz     VAT_ScanLoop                    ; loop back
   	
    mov esp, [StackStore]
	popad
	ret

; Drawing a 2D polygon which has DeltaV=0 and is opaque
align
PUBLIC ScanDraw2D_VAlignedOpaque_
PUBLIC _ScanDraw2D_VAlignedOpaque
ScanDraw2D_VAlignedOpaque_:
_ScanDraw2D_VAlignedOpaque:

	pushad
    mov [StackStore],esp
	mov     edx,_SCASM_ScanLength       

    mov     esi,_SCASM_StartU           ; get u 16.16 fixedpoint coordinate
    mov     esp,esi                     ; copy it
    sar     esi,16                      ; get integer part
    shl     esp,16                      ; get fractional part

    mov     eax,_SCASM_StartV           ; get v 16.16 fixedpoint coordinate
    sar     eax,16                      ; get integer part
    imul    eax,_SCASM_TextureDeltaScan ; calc texture scanline address
    add     esi,eax                     ; calc texture offset
    add     esi,_SCASM_Bitmap          ; calc address

	mov		edi,_SCASM_Destination
	
	mov     ebx,_SCASM_DeltaU                ; get u 16.16 step
    mov     ecx,ebx                     ; copy it
    sar     ebx,16                      ; get u int step
    shl     ecx,16                      ; get u frac step

	;	ebx		u int delta
	;	ecx		u frac delta
	;	esp		u frac total
	;	edi 	dest
	;	esi 	source
	;   edx		pixels to draw
VAO_ScanLoop:
    mov     al,[esi]                    ; get texture pixel 0
	add		esp,ecx
	
	adc		esi,ebx
	dec     edx              ; decrement span count
    
    mov     [edi],al          
	lea		edi,[edi+1]
	
    jnz     VAO_ScanLoop                    ; loop back
   	
    mov esp, [StackStore]
	popad
	ret


;
;  2d case with shading
;
;	mov eax,_SCASM_DeltaU
 ;	mov bl,ah
;	mov eax,_SCASM_DeltaV
 ;	mov cl,ah

if 0
align
PUBLIC ScanDraw2D_Gouraud_
PUBLIC _ScanDraw2D_Gouraud
ScanDraw2D_Gouraud_:
_ScanDraw2D_Gouraud:

; calculate horizontal deltas
	pushad
    
    mov 	[StackStore],esp
	mov     eax,_SCASM_ScanLength       
    
    mov		ebp,eax
 ;   and		eax,7
    
    shr     ebp,3                       
    mov		[PixelsRemaining],eax
    
    mov     [Wholesections],ebp          ; store widths
	mov     eax,_SCASM_DeltaV			; C1     1          ; get v 16.16 step
    
    mov     edx,_SCASM_DeltaU           ; C2	 1		    ; get u 16.16 step
    mov     ebx,eax                     ; C1	 2			; copy v 16.16 step

    sar     eax,16                      ; C1	 3			; get v int step
    mov     ecx,edx                     ; C2	 2			; copy u 16.16 step

    shl     ebx,16                      ; C1	 4			; get v frac step
    mov     esi,_SCASM_DeltaI           ; C3	 1			; get i 16.16 step
    
    sar     edx,16                      ; C2	 3			; get u int step
    mov     esp,esi                     ; C3	 2			; copy i 16.16 step
    
    shl     ecx,16                      ; C2	 4			; get u frac step
    mov     DeltaVFrac,ebx            	; C1	 5			; store it
  												 
    imul    eax,_SCASM_TextureDeltaScan ; C1	 6		    ; calculate texture step for v int step

    sar     esp,16-8                    ; C3	 3			; get i int step
  	mov     DeltaUFrac,ecx            	; C2	 5			; store it

    sar     esi,8                      ; C3	 4			; get i frac step
    add     eax,edx                     ; C1+C2	 1			; calculate uint + vint step
    
    mov     DeltaIFrac,esi      	    ; C3	 5			; store it
    mov     UVintVfracStepVNoCarry,eax	; C1+C2	 2			; save whole step in non-v-carry slot
    
	and		esp,0xffffff00h				; C3	 6
    add     eax,_SCASM_TextureDeltaScan ; C1+C2	 3	     	; calculate whole step + v carry

    mov     IintNoCarry,esp				; C3	 7			; save whole step in non-i-carry slot
	mov		edi,_SCASM_Destination
  
    mov     UVintVfracStepVCarry,eax	; C1+C2	 4			; save in v-carry slot
	add     esp,256						; C3	 8			; calculate whole step + i carry
    
    mov     IintWithCarry,esp  			; C3	 9			; save in i-carry slot
	mov		esp,_SCASM_StartI			; C4	 1

	mov		edx,esp						; C4	 2
    mov     esi,_SCASM_StartU           ; C5	 1			; get u 16.16 fixedpoint coordinate

	sar		esp,16-8					; C4	 3
    mov     ebx,esi                     ; C5	 2			; copy it

	sar		edx,8						; C4	 4
    mov     ecx,_SCASM_StartV           ; C6	 1			; get v 16.16 fixedpoint coordinate

	sar     esi,16                      ; C5	 3			; get integer part
	mov		eax,[edi]					; preread destination

    shl     ebx,16                      ; C5	 4			; get fractional part
	mov     eax,ecx                     ; C6	 2			; copy it
    
    sar     eax,16                      ; C6	 3			; get integer part
	and		esp,0xffffff00h				; C4	 5

	shl     ecx,16                      ; C6	 4			; get fractional part	shift [tears removal]
	add		esp,_SCASM_Lighting			; C4	 6
    
    imul    eax,_SCASM_TextureDeltaScan ; C6	 5			; calc texture scanline address


    add     esi,eax                     ; C7	 1			; calc texture offset
	xor 	eax,eax

    add     esi,_SCASM_Bitmap          	; C7	 2			; calc address
	test	ebp,ebp


	sar	ebx,16
	sar	ecx,16

	mov eax,_SCASM_DeltaU
	mov bl,ah
	mov eax,_SCASM_DeltaV
 	mov cl,ah
	
	mov		esp,[PixelsRemaining]
	add		edi,esp
	neg		esp
;	mov		eax,edx
;	add		ch,cl


 	jmp G3D_EndPixels
	jz		G3D_EndPixels
if 1
G3D_ScanLoop:
    ; 8 pixel span code
    ; edi = dest dib bits at current pixel
    ; esi = texture pointer at current u,v
    ; esp = lighting pointer
    ; ebx = u fraction 0.32
    ; ecx = v fraction 0.32	
    ; edx = i fraction 0.32
    ; ebp = carry scratch

;    mov     al,[edi]                    ; preread the destination cache line

    mov     al,[esi]                    ; get texture pixel 0
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
	add		ebx,DeltaUFrac

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi],al                  ; store pixel 0
	
	add		ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 1

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

 	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+1],al                  ; store pixel 1
	
	add		ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 2
				
    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

  	sbb		ebp,ebp
	mov 	al,[esp+eax]

  	add 	esp,[4*ebp + IintStep]
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+2],al                  ; store pixel 2

	add		ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 3

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+3],al                  ; store pixel 3

	add		ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 4

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+4],al                  ; store pixel 4

	add		ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 5

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac
			
 	sbb		ebp,ebp
	mov 	al,[esp+eax]

 	add 	esp,[4*ebp + IintStep]
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+5],al                  ; store pixel 5

	add		ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 6

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

 	sbb		ebp,ebp
	mov 	al,[esp+eax]

 	add 	esp,[4*ebp + IintStep]
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+6],al                  ; store pixel 6

	add		ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 7

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
    dec     Wholesections              ; decrement span count

    mov     [edi+7],al                  ; store pixel 7
	lea 	edi,[edi+8]

    jnz     G3D_ScanLoop                    ; loop back
endif   	

	mov		eax,[PixelsRemaining]
	test	eax,eax
	jz 		G3D_finish 
G3D_EndPixels:

  	add		ch,cl
	mov		eax,edx
	
    sbb     ebp,ebp                     ; get -1 if carry
    mov     al,[esi]      
   	
	inc		esp
  	add		bh,bl

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
   	add		edx,DeltaIFrac

	mov     al,[eax+_TLT]
	test	esp,esp

	mov 	[edi+esp],al
	jnz		G3D_EndPixels
G3D_finish:			   
    mov esp, [StackStore]
	popad
	ret

endif

 
;
;
;   NEW CODE
;
;

if 1
align
PUBLIC ScanDraw2D_Gouraud_
PUBLIC _ScanDraw2D_Gouraud
ScanDraw2D_Gouraud_:
_ScanDraw2D_Gouraud:

; calculate horizontal deltas
	pushad
    
    mov 	[StackStore],esp
	mov     eax,_SCASM_ScanLength       
    
    mov		ebp,eax
    and		eax,7
    
    shr     ebp,3                       
    mov		[PixelsRemaining],eax
    
    mov     [Wholesections],ebp          ; store widths
	mov     eax,_SCASM_DeltaV			; C1     1          ; get v 16.16 step
    
    mov     edx,_SCASM_DeltaU           ; C2	 1		    ; get u 16.16 step
    mov     ebx,eax                     ; C1	 2			; copy v 16.16 step

    sar     eax,16                      ; C1	 3			; get v int step
    mov     ecx,edx                     ; C2	 2			; copy u 16.16 step

    shl     ebx,16                      ; C1	 4			; get v frac step
    mov     esi,_SCASM_DeltaI           ; C3	 1			; get i 16.16 step
    
    sar     edx,16                      ; C2	 3			; get u int step
    mov     esp,esi                     ; C3	 2			; copy i 16.16 step
    
    shl     ecx,16                      ; C2	 4			; get u frac step
    mov     DeltaVFrac,ebx            	; C1	 5			; store it
  				  								 
    imul    eax,_SCASM_TextureDeltaScan ; C1	 6		    ; calculate texture step for v int step

    sar     esp,16-8                    ; C3	 3			; get i int step
  	mov     DeltaUFrac,ecx            	; C2	 5			; store it

    shl     esi,16                      ; C3	 4			; get i frac step
    add     eax,edx                     ; C1+C2	 1			; calculate uint + vint step
    
    mov     DeltaIFrac,esi      	    ; C3	 5			; store it
    mov     UVintVfracStepVNoCarry,eax	; C1+C2	 2			; save whole step in non-v-carry slot
    
	and		esp,0xffffff00h				; C3	 6
    add     eax,_SCASM_TextureDeltaScan ; C1+C2	 3	     	; calculate whole step + v carry

    mov     IintNoCarry,esp				; C3	 7			; save whole step in non-i-carry slot
	mov		edi,_SCASM_Destination
  
    mov     UVintVfracStepVCarry,eax	; C1+C2	 4			; save in v-carry slot
	add     esp,256						; C3	 8			; calculate whole step + i carry
    
    mov     IintWithCarry,esp  			; C3	 9			; save in i-carry slot
	mov		esp,_SCASM_StartI			; C4	 1

	mov		edx,esp						; C4	 2
    mov     esi,_SCASM_StartU           ; C5	 1			; get u 16.16 fixedpoint coordinate

	sar		esp,16-8					; C4	 3
    mov     ebx,esi                     ; C5	 2			; copy it

	shl		edx,16						; C4	 4
    mov     ecx,_SCASM_StartV           ; C6	 1			; get v 16.16 fixedpoint coordinate

	sar     esi,16                      ; C5	 3			; get integer part
	mov		eax,[edi]					; preread destination

 ;  shl     ebx,16                      ; C5	 4			; get fractional part
	and		ebx,0xffffh
	mov     eax,ecx                     ; C6	 2			; copy it
    
    sar     eax,16                      ; C6	 3			; get integer part
	and		esp,0xffffff00h				; C4	 5

;	shl     ecx,16                      ; C6	 4			; get fractional part	shift [tears removal]
	and		ecx,0xffffh
	add		esp,_SCASM_Lighting			; C4	 6
    
    imul    eax,_SCASM_TextureDeltaScan ; C6	 5			; calc texture scanline address


    add     esi,eax                     ; C7	 1			; calc texture offset
	mov 	eax,_SCASM_DeltaU

	mov 	bl,ah
	mov 	eax,_SCASM_DeltaV
 	
 	mov 	cl,ah
	xor 	eax,eax

    add     esi,_SCASM_Bitmap          	; C7	 2			; calc address
	test	ebp,ebp

 ;	jmp G3D_EndPixels
	jz		G3D_EndPixels
if 1
G3D_ScanLoop:
    ; 8 pixel span code
    ; edi = dest dib bits at current pixel
    ; esi = texture pointer at current u,v
    ; esp = lighting pointer
    ; ebx = u fraction 0.32
    ; ecx = v fraction 0.32	
    ; edx = i fraction 0.32
    ; ebp = carry scratch

;    mov     al,[edi]                    ; preread the destination cache line

    mov     al,[esi]                    ; get texture pixel 0
  ; add		ecx,DeltaVFrac;test to remove tears
	add		ch,cl

    sbb     ebp,ebp                     ; get -1 if carry
;	add		ebx,DeltaUFrac
	add		bh,bl

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
 ;  	add		ecx,DeltaVFrac;test to remove tears
	add		ch,cl

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi],al                  ; store pixel 0
	
;	add		ebx,DeltaUFrac
	add		bh,bl
    mov     al,[esi]                    ; get texture pixel 1

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

 	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
;   	add		ecx,DeltaVFrac;test to remove tears
	add		ch,cl

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+1],al                  ; store pixel 1
	
 ;	add		ebx,DeltaUFrac
	add		bh,bl
    mov     al,[esi]                    ; get texture pixel 2
				
    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

  	sbb		ebp,ebp
	mov 	al,[esp+eax]

  	add 	esp,[4*ebp + IintStep]
 ;  	add		ecx,DeltaVFrac;test to remove tears
	add		ch,cl

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+2],al                  ; store pixel 2

;	add		ebx,DeltaUFrac
	add		bh,bl
    mov     al,[esi]                    ; get texture pixel 3

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
;   	add		ecx,DeltaVFrac;test to remove tears
	add		ch,cl

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+3],al                  ; store pixel 3

;	add		ebx,DeltaUFrac
	add		bh,bl
    mov     al,[esi]                    ; get texture pixel 4

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
 ;  	add		ecx,DeltaVFrac;test to remove tears
	add		ch,cl

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+4],al                  ; store pixel 4

;	add		ebx,DeltaUFrac
	add		bh,bl
    mov     al,[esi]                    ; get texture pixel 5

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac
			
 	sbb		ebp,ebp
	mov 	al,[esp+eax]

 	add 	esp,[4*ebp + IintStep]
  ; 	add		ecx,DeltaVFrac;test to remove tears
	add		ch,cl

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+5],al                  ; store pixel 5

;	add		ebx,DeltaUFrac
	add		bh,bl
    mov     al,[esi]                    ; get texture pixel 6

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

 	sbb		ebp,ebp
	mov 	al,[esp+eax]

 	add 	esp,[4*ebp + IintStep]
;   	add		ecx,DeltaVFrac;test to remove tears
	add		ch,cl

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+6],al                  ; store pixel 6

 ;	add		ebx,DeltaUFrac
	add		bh,bl
    mov     al,[esi]                    ; get texture pixel 7

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add		edx,DeltaIFrac

	sbb		ebp,ebp
	mov 	al,[esp+eax]

	add 	esp,[4*ebp + IintStep]
    dec     Wholesections              ; decrement span count

    mov     [edi+7],al                  ; store pixel 7
	lea 	edi,[edi+8]

    jnz     G3D_ScanLoop                    ; loop back
endif   	

	mov		eax,[PixelsRemaining]
	test	eax,eax
	jz 		G3D_finish 
G3D_EndPixels:

    mov     eax,[esi]      
	add		ch,cl
;   	add		ecx,DeltaVFrac
    
    sbb     ebp,ebp                     ; get -1 if carry
	and		eax,0xffh

	add		bh,bl
;	add		ebx,DeltaUFrac
	lea 	edi,[edi+1]

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
   	add		edx,DeltaIFrac

	sbb		ebp,ebp
	mov     al,[esp+eax]                
	
	mov 	[edi-1],al
	mov		eax,[PixelsRemaining]

	add 	esp,[4*ebp + IintStep]
	dec		eax
;	dec		[PixelsRemaining]
	
	mov		[PixelsRemaining],eax
	jnz		G3D_EndPixels
G3D_finish:			   
    mov esp, [StackStore]
	popad
	ret
endif
;
;
;   NEW CODE
;
;

align
PUBLIC ScanDraw2D_GouraudTransparent_
PUBLIC _ScanDraw2D_GouraudTransparent
ScanDraw2D_GouraudTransparent_:
_ScanDraw2D_GouraudTransparent:

; calculate horizontal deltas
	pushad
    mov 	[StackStore],esp
	
	mov     eax,_SCASM_ScanLength       
	mov		[PixelsRemaining],eax

    mov     eax,_SCASM_DeltaV                ; get v 16.16 step
    mov     ebx,eax                     ; copy it
    sar     eax,16                      ; get v int step
    shl     ebx,16                      ; get v frac step
    mov     DeltaVFrac,ebx            ; store it
  
    imul    eax,_SCASM_TextureDeltaScan      ; calculate texture step for v int step

    mov     ebx,_SCASM_DeltaU                ; get u 16.16 step
    mov     ecx,ebx                     ; copy it
    sar     ebx,16                      ; get u int step
    shl     ecx,16                      ; get u frac step
  
    mov     DeltaUFrac,ecx            ; store it
    add     eax,ebx                     ; calculate uint + vint step
    mov     UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
    add     eax,_SCASM_TextureDeltaScan      ; calculate whole step + v carry
    mov     UVintVfracStepVCarry,eax  ; save in v-carry slot

    ; setup initial coordinates
    mov     edx,_SCASM_DeltaI           ; get i 16.16 step
    mov     eax,edx                     ; copy it
    sar     eax,16                      ; get i int step
    shl     edx,16                      ; get i frac step
    mov     DeltaIFrac,edx      	    ; store it
    imul    eax,_SCASM_ShadingTableSize
    mov     IintNoCarry,eax				; save whole step in non-i-carry slot
    add     eax,_SCASM_ShadingTableSize      	; calculate whole step + i carry
    mov     IintWithCarry,eax  			; save in i-carry slot

	mov		esp,_SCASM_StartI
	mov		edx,esp
	sar		esp,16
	shl		edx,16
	imul	esp,_SCASM_ShadingTableSize
	add		esp,_SCASM_Lighting

    mov     esi,_SCASM_StartU                ; get u 16.16 fixedpoint coordinate
    mov     ebx,esi                     ; copy it
    sar     esi,16                      ; get integer part
    shl     ebx,16                      ; get fractional part

    mov     ecx,_SCASM_StartV                ; get v 16.16 fixedpoint coordinate
    mov     eax,ecx                     ; copy it
    sar     eax,16                      ; get integer part
    shl     ecx,16                      ; get fractional part	shift [tears removal]
    imul    eax,_SCASM_TextureDeltaScan      ; calc texture scanline address
    add     esi,eax                     ; calc texture offset
    add     esi,_SCASM_Bitmap          ; calc address


;	mov eax,_SCASM_DeltaU
 ;	mov bl,ah
;	mov eax,_SCASM_DeltaV
 ;	mov cl,ah

	xor eax,eax
	mov	edi,_SCASM_Destination
	
G2DT_EndPixels:

    mov     al,[esi]          ; get texture pixel  
   	add		ecx,DeltaVFrac;test to remove tears
    
    sbb     ebp,ebp                     ; get -1 if carry
	test	eax,eax
	
	jz		G2DT_SkipPixel
	
	mov     al,[esp+eax]                  ; store pixel 0
	mov 	[edi],al
	
	
	G2DT_SkipPixel:
	
	lea 	edi,[edi+1]
	add		ebx,DeltaUFrac
        
    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
   	add		edx,DeltaIFrac
	
	sbb		ebp,ebp
	add 	esp,[4*ebp + IintStep]
	
	dec		[PixelsRemaining]
	jnz		G2DT_EndPixels

    mov esp, [StackStore]
	popad
	ret







align
PUBLIC ScanDraw2D_Opaque_
PUBLIC _ScanDraw2D_Opaque
ScanDraw2D_Opaque_:
_ScanDraw2D_Opaque:

; calculate horizontal deltas
	pushad
    mov [StackStore],esp

	mov     eax,_SCASM_ScanLength       
    mov		ebp,eax
    
  	and		eax,7
    shr     ebp,3                       
    
	mov		[PixelsRemaining],eax
    mov     [Wholesections],ebp          ; store widths
	

    mov     eax,_SCASM_DeltaV                ; get v 16.16 step
    mov     ebx,eax                     ; copy it
    sar     eax,16                      ; get v int step
    shl     ebx,16                      ; get v frac step
    mov     DeltaVFrac,ebx            ; store it
    ;shl		eax,7
    imul    eax,_SCASM_TextureDeltaScan      ; calculate texture step for v int step

    mov     ebx,_SCASM_DeltaU                ; get u 16.16 step
    mov     ecx,ebx                     ; copy it
    sar     ebx,16                      ; get u int step
    shl     ecx,16                      ; get u frac step
    mov     DeltaUFrac,ecx            ; store it
    add     eax,ebx                     ; calculate uint + vint step
    mov     UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
    add     eax,_SCASM_TextureDeltaScan      ; calculate whole step + v carry
    mov     UVintVfracStepVCarry,eax  ; save in v-carry slot

    ; setup initial coordinates

    mov     esi,_SCASM_StartU                ; get u 16.16 fixedpoint coordinate
    mov     ebx,esi                     ; copy it
    sar     esi,16                      ; get integer part
    shl     ebx,16                      ; get fractional part

    mov     ecx,_SCASM_StartV                ; get v 16.16 fixedpoint coordinate
    mov     edx,ecx                     ; copy it
    sar     edx,16                      ; get integer part
    shl     ecx,16                      ; get fractional part
   ; shl		edx,7
    imul    edx,_SCASM_TextureDeltaScan      ; calc texture scanline address
    add     esi,edx                     ; calc texture offset
    add     esi,_SCASM_Bitmap          ; calc address

    mov     edx,DeltaUFrac            ; get register copy
	mov		esp,DeltaVFrac
	mov		edi,_SCASM_Destination

	test ebp,ebp
	jz O2D_EndPixels
	
if 1
O2D_ScanLoop:
    ; 8 pixel span code
    ; edi = dest dib bits at current pixel
    ; esi = texture pointer at current u,v
    ; ebx = u fraction 0.32
    ; ecx = v fraction 0.32
    ; edx = u frac step
    ; ebp = v carry scratch

;    mov     al,[edi]                    ; preread the destination cache line

    mov     al,[esi]                    ; get texture pixel 0
 
    add     ecx,esp            ; increment v fraction
    sbb     ebp,ebp                     ; get -1 if carry
    add     ebx,edx                     ; increment u fraction

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add     ecx,esp            ; increment v fraction

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+0],al                  ; store pixel 0
	
    add     ebx,edx                     ; increment u fraction
    mov     al,[esi]                    ; get texture pixel 1

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add     ecx,esp            ; increment v fraction

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+1],al                  ; store pixel 1
	
    add     ebx,edx                     ; increment u fraction
    mov     al,[esi]                    ; get texture pixel 2
				
    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add     ecx,esp            ; increment v fraction

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+2],al                  ; store pixel 2

    add     ebx,edx                     ; increment u fraction
    mov     al,[esi]                    ; get texture pixel 3

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add     ecx,esp            ; increment v fraction

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+3],al                  ; store pixel 3

    add     ebx,edx                     ; increment u fraction
    mov     al,[esi]                    ; get texture pixel 4

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add     ecx,esp            ; increment v fraction

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+4],al                  ; store pixel 4

    add     ebx,edx                     ; increment u fraction
    mov     al,[esi]                    ; get texture pixel 5

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add     ecx,esp            ; increment v fraction

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+5],al                  ; store pixel 5

    add     ebx,edx                     ; increment u fraction
    mov     al,[esi]                    ; get texture pixel 6

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    add     ecx,esp            ; increment v fraction

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+6],al                  ; store pixel 6

    add     ebx,edx                     ; increment u fraction
    mov     al,[esi]                    ; get texture pixel 7

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries

    mov     [edi+7],al                  ; store pixel 7


    add     edi,8                       ; increment to next span
    dec     Wholesections              ; decrement span count
    jnz     O2D_ScanLoop                    ; loop back
endif   	

	mov		eax,[PixelsRemaining]
	test	eax,eax
	jz 		O2D_finish 
O2D_EndPixels:

    mov     al,[esi]          ; get texture pixel  
   	add		ecx,esp				; increment v fraction
    
    sbb     ebp,ebp                     ; get -1 if carry
    add     ebx,edx                     ; increment u fraction
	
	mov     [edi],al                  ; store pixel 
    lea 	edi,[edi+1]

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
	dec		[PixelsRemaining]
	
	jnz		O2D_EndPixels
   	


O2D_finish:
    mov esp, [StackStore]
	popad
	ret


align
PUBLIC ScanDraw2D_Transparent_
PUBLIC _ScanDraw2D_Transparent
ScanDraw2D_Transparent_:
_ScanDraw2D_Transparent:

; calculate horizontal deltas
	pushad
    mov [StackStore],esp

	mov     ebp,_SCASM_ScanLength       
	mov		[PixelsRemaining],ebp

    mov     eax,_SCASM_DeltaV                ; get v 16.16 step
    mov     ebx,eax                     ; copy it
    sar     eax,16                      ; get v int step
    shl     ebx,16                      ; get v frac step
    mov     DeltaVFrac,ebx            ; store it
    ;shl		eax,7
    imul    eax,_SCASM_TextureDeltaScan      ; calculate texture step for v int step

    mov     ebx,_SCASM_DeltaU                ; get u 16.16 step
    mov     ecx,ebx                     ; copy it
    sar     ebx,16                      ; get u int step
    shl     ecx,16                      ; get u frac step
    mov     DeltaUFrac,ecx            ; store it
    add     eax,ebx                     ; calculate uint + vint step
    mov     UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
    add     eax,_SCASM_TextureDeltaScan      ; calculate whole step + v carry
    mov     UVintVfracStepVCarry,eax  ; save in v-carry slot

    ; setup initial coordinates

    mov     esi,_SCASM_StartU                ; get u 16.16 fixedpoint coordinate
    mov     ebx,esi                     ; copy it
    sar     esi,16                      ; get integer part
    shl     ebx,16                      ; get fractional part

    mov     ecx,_SCASM_StartV                ; get v 16.16 fixedpoint coordinate
    mov     edx,ecx                     ; copy it
    sar     edx,16                      ; get integer part
    shl     ecx,16                      ; get fractional part
   ; shl		edx,7
    imul    edx,_SCASM_TextureDeltaScan      ; calc texture scanline address
    add     esi,edx                     ; calc texture offset
    add     esi,_SCASM_Bitmap          ; calc address

    mov     edx,DeltaUFrac            ; get register copy
	mov		esp,DeltaVFrac
	mov		edi,_SCASM_Destination

T2D_EndPixels:

    mov     al,[esi]          ; get texture pixel  
   	add		ecx,esp				; increment v fraction
    
    sbb     ebp,ebp                     ; get -1 if carry
	test	al,al
	
	jz		T2D_SkipPixel
	
	mov     [edi],al                  ; store pixel 
    T2D_SkipPixel:
    
    lea 	edi,[edi+1]
    add     ebx,edx                     ; increment u fraction

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
	dec		[PixelsRemaining]
	
	jnz		T2D_EndPixels
   	
    mov esp, [StackStore]
	popad
	ret

align
PUBLIC ScanDraw2D_TransparentLit_
PUBLIC _ScanDraw2D_TransparentLit
ScanDraw2D_TransparentLit_:
_ScanDraw2D_TransparentLit:

; calculate horizontal deltas
	pushad
    mov [StackStore],esp

	mov     ebp,_SCASM_ScanLength       
	mov		[PixelsRemaining],ebp

	mov		esp,_SCASM_StartI
	imul	esp,_SCASM_ShadingTableSize
	add		esp,_SCASM_Lighting

    mov     eax,_SCASM_DeltaV                ; get v 16.16 step
    mov     ebx,eax                     ; copy it
    sar     eax,16                      ; get v int step
    shl     ebx,16                      ; get v frac step
    mov     DeltaVFrac,ebx            ; store it
    ;shl		eax,7
    imul    eax,_SCASM_TextureDeltaScan      ; calculate texture step for v int step

    mov     ebx,_SCASM_DeltaU                ; get u 16.16 step
    mov     ecx,ebx                     ; copy it
    sar     ebx,16                      ; get u int step
    shl     ecx,16                      ; get u frac step
    mov     DeltaUFrac,ecx            ; store it
    add     eax,ebx                     ; calculate uint + vint step
    mov     UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
    add     eax,_SCASM_TextureDeltaScan      ; calculate whole step + v carry
    mov     UVintVfracStepVCarry,eax  ; save in v-carry slot

    ; setup initial coordinates

    mov     esi,_SCASM_StartU                ; get u 16.16 fixedpoint coordinate
    mov     ebx,esi                     ; copy it
    sar     esi,16                      ; get integer part
    shl     ebx,16                      ; get fractional part

    mov     ecx,_SCASM_StartV                ; get v 16.16 fixedpoint coordinate
    mov     edx,ecx                     ; copy it
    sar     edx,16                      ; get integer part
    shl     ecx,16                      ; get fractional part
   ; shl		edx,7
    imul    edx,_SCASM_TextureDeltaScan      ; calc texture scanline address
    add     esi,edx                     ; calc texture offset
    add     esi,_SCASM_Bitmap          ; calc address

    mov     edx,DeltaUFrac            ; get register copy
 ;	mov		esp,DeltaVFrac
	mov		edi,_SCASM_Destination
	xor		eax,eax

TL2D_EndPixels:

    mov     al,[esi]          ; get texture pixel  
   	add		ecx,DeltaVFrac				; increment v fraction
    
    sbb     ebp,ebp                     ; get -1 if carry
	test	al,al
	
	jz		TL2D_SkipPixel
	
	mov		al,[eax+esp]
	mov     [edi],al                  ; store pixel 
    TL2D_SkipPixel:
    
    lea 	edi,[edi+1]
    add     ebx,edx                     ; increment u fraction

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
	dec		[PixelsRemaining]
	
	jnz		TL2D_EndPixels
   	
    mov esp, [StackStore]
	popad
	ret

if 0
PUBLIC MotionTrackerRotateBlit_
MotionTrackerRotateBlit_:

; calculate horizontal deltas
	pushad
    mov [StackStore],esp


	mov	eax,_MTRB_Angle
	mov	eax,[_cosine + eax * 4]
	shl	eax,16 - 7 
  	imul	[_MTRB_InvScale]
  	shrd	eax,edx,16
	mov	[dUCol],eax


	mov	eax,[_MTRB_Angle]
	mov	eax,[_sine + eax * 4]
	shl	eax,16 - 7 
	imul	[_MTRB_InvScale]
  	shrd	eax,edx,16
	mov	[dVCol],eax
    mov esp,eax
; calculate vertical deltas

	mov	eax,[dVCol]
	neg	eax
 ;	imul	[aspectAdjust]
 ; 	shrd	eax,edx,16
	mov	[dURow],eax

	mov	eax,[dUCol]
;	imul	[aspectAdjust]
; 	shrd	eax,edx,16
	mov	[dVRow],eax

	mov	eax,_MTRB_CentreU       ; put CentreU&V in 16.16 for now
	shl	eax,16-7
	mov	[startingU],eax
	mov	eax,_MTRB_CentreV
	shl	eax,16-7
	mov	[startingV],eax


; move up by yOrg

	mov	eax,[dUCol]
	imul    eax,_MTRB_ScreenCentreX
	sub	[startingU],eax

	mov	eax,[dURow]
	imul	eax,_MTRB_ScreenCentreY
	sub	[startingU],eax

	mov	eax,[dVCol]
	imul	eax,_MTRB_ScreenCentreX
	sub	[startingV],eax
		 
	mov	eax,[dVRow]
	imul	eax,_MTRB_ScreenCentreY
	sub	[startingV],eax

; fixup end of row deltas

	mov	eax,[dUCol]
	imul	eax,_MTRB_ScreenWidth
	neg	eax
	add	eax,[dURow]
 	mov	[dURow],eax


	mov	eax,[dVCol]
	imul	eax,_MTRB_ScreenWidth
	neg	eax
	add	eax,[dVRow]
    mov	[dVRow],eax



	mov	esi,[_MTRB_Bitmap]
	mov	edi,[_MTRB_Destination]

	mov	ecx,[startingU]
	mov	edx,[startingV]

	mov	ebx,_MTRB_ScreenHeight		; initialize row count
	mov ah,bl
MTRB_RowLoop:
   	mov	ebx,_MTRB_ScreenWidth 		; initialize column count

MTRB_ColLoop:
 	mov	ebp,edx
	shr	ebp,32 - 7
	shld ebp,ecx,7

   	add	edx,esp
    add	ecx,[dUCol]

	mov	al,[esi+ebp]
  	test al,al
	jz MTRB_SkipPixel
	mov	[edi],al
	MTRB_SkipPixel:
 	
   	lea edi,[edi+1]

   	dec	ebx

    jnz	MTRB_ColLoop

    add	ecx,[dURow]
   	add	edx,[dVRow]
	add	edi,[_MTRB_ScanOffset]

    dec	ah
	jnz	MTRB_RowLoop


    mov esp, [StackStore]
	popad
	ret

PUBLIC MotionTrackerRotateBlit8_
PUBLIC _MotionTrackerRotateBlit8
MotionTrackerRotateBlit8_:
_MotionTrackerRotateBlit8:

; calculate horizontal deltas
	pushad
    mov [StackStore],esp


	mov	eax,_MTRB_Angle
	mov	eax,[_cosine + eax * 4]
	shl	eax,16 - 8 
  	imul	[_MTRB_InvScale]
  	shrd	eax,edx,16
	mov	[dUCol],eax


	mov	eax,[_MTRB_Angle]
	mov	eax,[_sine + eax * 4]
	shl	eax,16 - 8 
	imul	[_MTRB_InvScale]
  	shrd	eax,edx,16
	mov	[dVCol],eax
    mov esp,eax
; calculate vertical deltas

	mov	eax,[dVCol]
	neg	eax
 ;	imul	[aspectAdjust]
 ; 	shrd	eax,edx,16
	mov	[dURow],eax

	mov	eax,[dUCol]
;	imul	[aspectAdjust]
; 	shrd	eax,edx,16
	mov	[dVRow],eax

	mov	eax,_MTRB_CentreU       ; put CentreU&V in 16.16 for now
	shl	eax,16-8
	mov	[startingU],eax
	mov	eax,_MTRB_CentreV
	shl	eax,16-8
	mov	[startingV],eax


; move up by yOrg

	mov	eax,[dUCol]
	imul    eax,_MTRB_ScreenCentreX
	sub	[startingU],eax

	mov	eax,[dURow]
	imul	eax,_MTRB_ScreenCentreY
	sub	[startingU],eax

	mov	eax,[dVCol]
	imul	eax,_MTRB_ScreenCentreX
	sub	[startingV],eax
		 
	mov	eax,[dVRow]
	imul	eax,_MTRB_ScreenCentreY
	sub	[startingV],eax

; fixup end of row deltas

	mov	eax,[dUCol]
	imul	eax,_MTRB_ScreenWidth
	neg	eax
	add	eax,[dURow]
 	mov	[dURow],eax


	mov	eax,[dVCol]
	imul	eax,_MTRB_ScreenWidth
	neg	eax
	add	eax,[dVRow]
    mov	[dVRow],eax



	mov	esi,[_MTRB_Bitmap]
	mov	edi,[_MTRB_Destination]

	mov	ecx,[startingU]
	mov	edx,[startingV]

	mov	ebx,_MTRB_ScreenHeight		; initialize row count
	mov ah,bl
MTRB_RowLoop8:
   	mov	ebx,_MTRB_ScreenWidth 		; initialize column count

MTRB_ColLoop8:
 	mov	ebp,edx
	shr	ebp,32 - 8
	shld ebp,ecx,8

   	add	edx,esp
    add	ecx,[dUCol]

	mov	al,[esi+ebp]
  	test al,al
	jz MTRB_SkipPixel8
	mov	[edi],al
	MTRB_SkipPixel8:
 	
   	lea edi,[edi+1]

   	dec	ebx

    jnz	MTRB_ColLoop8

    add	ecx,[dURow]
   	add	edx,[dVRow]
	add	edi,[_MTRB_ScanOffset]

    dec	ah
	jnz	MTRB_RowLoop8


    mov esp, [StackStore]
	popad
	ret
endif






; floating point test area
if 0

PUBLIC ScanDrawF3D_Gouraud_
ScanDrawF3D_Gouraud_:

; calculate horizontal deltas

	pushad
 
    ; put the FPU in 32 bit mode
    ; @todo move this out of here!
;    fstcw   [OldFPUCW]                  ; store copy of CW
 ;   mov     ax,OldFPUCW                 ; get it in ax
;    and     eax,NOT 1100000000y         ; 24 bit precision
;    mov     [FPUCW],ax                  ; store it
;    fldcw   [FPUCW]                     ; load the FPU
 	finit
 ;   mov 	[StackStore],esp
	
	mov     eax,_SCASM_ScanLength       
    mov		ebp,eax
    
  	and		eax,7
    shr     ebp,3                       
    
	mov		[PixelsRemaining],eax
    mov     [Wholesections],ebp          ; store widths

if 0
    ; setup initial coordinates
    mov     edx,_SCASM_DeltaI           ; get i 16.16 step
    mov     eax,edx                     ; copy it
    sar     eax,16                      ; get i int step
    shl     edx,16                      ; get i frac step
    mov     DeltaIFrac,edx      	    ; store it
    imul    eax,_SCASM_ShadingTableSize
    mov     IintNoCarry,eax				; save whole step in non-i-carry slot
    add     eax,_SCASM_ShadingTableSize      	; calculate whole step + i carry
    mov     IintWithCarry,eax  			; save in i-carry slot

	mov		esp,_SCASM_StartI
	mov		edx,esp
	sar		esp,16
	shl		edx,16
	imul	esp,_SCASM_ShadingTableSize
	add		esp,_SCASM_Lighting
endif
	;******************************************************************************************
	mov     ebx,_ScanDescPtr

    ; calculate ULeft and VLeft         ; FPU Stack (ZL = ZLeft)
                                        ; st0  st1  st2  st3  st4  st5  st6  st7
    fld     DWORD PTR [ebx+4]			            ; V/ZL 
    fld     DWORD PTR [ebx]           		    ; U/ZL V/ZL 
    fld     DWORD PTR [ebx+8]              		; 1/ZL U/ZL V/ZL 
    fld1                                ; 1    1/ZL U/ZL V/ZL 
    fdiv    st,st(1)                    ; ZL   1/ZL U/ZL V/ZL 
    fld     st                          ; ZL   ZL   1/ZL U/ZL V/ZL 
    fmul    st,st(4)                    ; VL   ZL   1/ZL U/ZL V/ZL 
    fxch    st(1)                       ; ZL   VL   1/ZL U/ZL V/ZL 
    fmul    st,st(3)                    ; UL   VL   1/ZL U/ZL V/ZL 

    fstp    st(5)                       ; VL   1/ZL U/ZL V/ZL UL
    fstp    st(5)                       ; 1/ZL U/ZL V/ZL UL   VL

    ; calculate right side OverZ terms  ; st0  st1  st2  st3  st4  st5  st6  st7

    fadd    DWORD PTR [ebx+20]          ; 1/ZR U/ZL V/ZL UL   VL
    fxch    st(1)                       ; U/ZL 1/ZR V/ZL UL   VL
    fadd    DWORD PTR [ebx+12]            ; U/ZR 1/ZR V/ZL UL   VL
    fxch    st(2)            ; V/ZL 1/ZR U/ZR UL   VL
    fadd    DWORD PTR [ebx+16]            ; V/ZR 1/ZR U/ZR UL   VL
    
    ; calculate right side coords       ; st0  st1  st2  st3  st4  st5  st6  st7

    fld1                                ; 1    V/ZR 1/ZR U/ZR UL   VL
    ; @todo overlap this guy
    fdiv    st,st(2)                    ; ZR   V/ZR 1/ZR U/ZR UL   VL
    fld     st                          ; ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
    fmul    st,st(2)                    ; VR   ZR   V/ZR 1/ZR U/ZR UL   VL
    fxch    st(1)                       ; ZR   VR   V/ZR 1/ZR U/ZR UL   VL
    fmul    st,st(4)                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL
	;******************************************************************************************
	xor eax,eax
	mov	edi,_SCASM_Destination
	
	test ebp,ebp
	jz GF3D_EndPixels

GF3D_ScanLoop:
    ; at this point the FPU contains    ; st0  st1  st2  st3  st4  st5  st6  st7
                                        ; UR   VR   V/ZR 1/ZR U/ZR UL   VL

    ; convert left side coords

    fld     st(5)                       ; UL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
    fmul    [FixedScale]                ; UL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
    fistp   [_SCASM_StartU]                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL

    fld     st(6)                       ; VL   UR   VR   V/ZR 1/ZR U/ZR UL   VL
    fmul    [FixedScale]               ; VL16 UR   VR   V/ZR 1/ZR U/ZR UL   VL
    fistp   [_SCASM_StartV]                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL

    ; calculate deltas                  ; st0  st1  st2  st3  st4  st5  st6  st7

    fsubr   st(5),st                    ; UR   VR   V/ZR 1/ZR U/ZR dU   VL
    fxch    st(1)                       ; VR   UR   V/ZR 1/ZR U/ZR dU   VL
    fsubr   st(6),st                    ; VR   UR   V/ZR 1/ZR U/ZR dU   dV
    fxch    st(6)                       ; dV   UR   V/ZR 1/ZR U/ZR dU   VR

    fmul    [FixedScale8]               ; dV8  UR   V/ZR 1/ZR U/ZR dU   VR
    fistp   [_SCASM_DeltaV]                    ; UR   V/ZR 1/ZR U/ZR dU   VR

    fxch    st(4)                       ; dU   V/ZR 1/ZR U/ZR UR   VR
    fmul    [FixedScale8]               ; dU8  V/ZR 1/ZR U/ZR UR   VR
    fistp   [_SCASM_DeltaU]                    ; V/ZR 1/ZR U/ZR UR   VR

    ; increment terms for next span     ; st0  st1  st2  st3  st4  st5  st6  st7
    ; Right terms become Left terms---->; V/ZL 1/ZL U/ZL UL   VL

    mov     ebx,_ScanDescPtr
    fadd    DWORD PTR [ebx+16]            ; V/ZR 1/ZL U/ZL UL   VL
    fxch    st(1)                       ; 1/ZL V/ZR U/ZL UL   VL
    fadd    DWORD PTR [ebx+20]          ; 1/ZR V/ZR U/ZL UL   VL
    fxch    st(2)                       ; U/ZL V/ZR 1/ZR UL   VL
    fadd    DWORD PTR [ebx+12]            ; U/ZR V/ZR 1/ZR UL   VL
    fxch    st(2)                       ; 1/ZR V/ZR U/ZR UL   VL
    fxch    st(1)                       ; V/ZR 1/ZR U/ZR UL   VL

    ; calculate right side coords       ; st0  st1  st2  st3  st4  st5  st6  st7

    fld1                                ; 1    V/ZR 1/ZR U/ZR UL   VL
    fdiv    st,st(2)                    ; ZR   V/ZR 1/ZR U/ZR UL   VL

    ; set up affine registers

    ; setup delta values
    
    mov     eax,_SCASM_DeltaV                ; get v 16.16 step
    mov     ebx,eax                     ; copy it
    sar     eax,16                      ; get v int step
    shl     ebx,16                      ; get v frac step
    mov     DeltaVFrac,ebx            ; store it
  
    imul    eax,_SCASM_TextureDeltaScan      ; calculate texture step for v int step

    mov     ebx,_SCASM_DeltaU                ; get u 16.16 step
    mov     ecx,ebx                     ; copy it
    sar     ebx,16                      ; get u int step
    shl     ecx,16                      ; get u frac step
  
    mov     DeltaUFrac,ecx            ; store it
    add     eax,ebx                     ; calculate uint + vint step
    mov     UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
    add     eax,_SCASM_TextureDeltaScan      ; calculate whole step + v carry
    mov     UVintVfracStepVCarry,eax  ; save in v-carry slot


    mov     esi,_SCASM_StartU                ; get u 16.16 fixedpoint coordinate
    mov     ebx,esi                     ; copy it
    sar     esi,16                      ; get integer part
    shl     ebx,16                      ; get fractional part

    mov     ecx,_SCASM_StartV                ; get v 16.16 fixedpoint coordinate
    mov     eax,ecx                     ; copy it
    sar     eax,16                      ; get integer part
    shl     ecx,16                      ; get fractional part	shift [tears removal]
    imul    eax,_SCASM_TextureDeltaScan      ; calc texture scanline address
    add     esi,eax                     ; calc texture offset
    add     esi,_SCASM_Bitmap          ; calc address


    ; 8 pixel span code
    ; edi = dest dib bits at current pixel
    ; esi = texture pointer at current u,v
    ; esp = lighting pointer
    ; ebx = u fraction 0.32
    ; ecx = v fraction 0.32
    ; edx = i fraction 0.32
    ; ebp = carry scratch

;    mov     al,[edi]                    ; preread the destination cache line

    mov     al,[esi]                    ; get texture pixel 0
 
   	add		ecx,DeltaVFrac;test to remove tears
    sbb     ebp,ebp                     ; get -1 if carry
	add	ebx,DeltaUFrac
    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
   
;   add	edx,DeltaIFrac
;	sbb	ebp,ebp
;	mov al,[esp+eax]
;	add esp,[4*ebp + IintStep]
   
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi],al                  ; store pixel 0
	
	add	ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 1

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    
;    add	edx,DeltaIFrac
; 	sbb	ebp,ebp
;	mov al,[esp+eax]
;	add esp,[4*ebp + IintStep]
    
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+1],al                  ; store pixel 1
	
	add	ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 2
				
    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries

;    add	edx,DeltaIFrac
;  	sbb	ebp,ebp
;	mov al,[esp+eax]
;  	add esp,[4*ebp + IintStep]

   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+2],al                  ; store pixel 2

	add	ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 3

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
    
;    add	edx,DeltaIFrac
;	sbb	ebp,ebp
;	mov al,[esp+eax]
;	add esp,[4*ebp + IintStep]
    
   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+3],al                  ; store pixel 3

	add	ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 4

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries

;    add	edx,DeltaIFrac
;	sbb	ebp,ebp
;	mov al,[esp+eax]
;	add esp,[4*ebp + IintStep]

   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+4],al                  ; store pixel 4

	add	ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 5

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries

;    add	edx,DeltaIFrac
; 	sbb	ebp,ebp
;	mov al,[esp+eax]
; 	add esp,[4*ebp + IintStep]

   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+5],al                  ; store pixel 5

	add	ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 6

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries

;    add	edx,DeltaIFrac
; 	sbb	ebp,ebp
;	mov al,[esp+eax]
; 	add esp,[4*ebp + IintStep]

   	add		ecx,DeltaVFrac;test to remove tears

    sbb     ebp,ebp                     ; get -1 if carry
    mov     [edi+6],al                  ; store pixel 6

	add	ebx,DeltaUFrac
    mov     al,[esi]                    ; get texture pixel 7

    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries

;    add	edx,DeltaIFrac
;	sbb	ebp,ebp
;	mov al,[esp+eax]
;	add esp,[4*ebp + IintStep]
    dec     Wholesections              ; decrement span count


    mov     [edi+7],al                  ; store pixel 7
	lea edi,[edi+8]


    ; the fdiv is done, finish right    ; st0  st1  st2  st3  st4  st5  st6  st7
                                        ; ZR   V/ZR 1/ZR U/ZR UL   VL

    fld     st                          ; ZR   ZR   V/ZR 1/ZR U/ZR UL   VL
    fmul    st,st(2)                    ; VR   ZR   V/ZR 1/ZR U/ZR UL   VL
    fxch    st(1)                       ; ZR   VR   V/ZR 1/ZR U/ZR UL   VL
    fmul    st,st(4)                    ; UR   VR   V/ZR 1/ZR U/ZR UL   VL

    jnz     GF3D_ScanLoop                    ; loop back

	mov		eax,[PixelsRemaining]
	test	eax,eax
	jz 		GF3D_finish 
GF3D_EndPixels:
if 0
    mov     al,[esi]          ; get texture pixel  
   	add		ecx,DeltaVFrac;test to remove tears
    
    sbb     ebp,ebp                     ; get -1 if carry
	add	ebx,DeltaUFrac
	
	lea 	edi,[edi+1]
	mov     al,[esp+eax]                  ; store pixel 0
        
    adc     esi,[4*ebp+UVintVfracStep]  ; add in step ints & carries
   	add		edx,DeltaIFrac
	
	sbb		ebp,ebp
	mov 	[edi-1],al
	
	add 	esp,[4*ebp + IintStep]
	dec		[PixelsRemaining]
	
	jnz		GF3D_EndPixels
endif

FPUReturn:

    ; busy FPU registers:               ; st0  st1  st2  st3  st4  st5  st6  st7
                                        ; xxx  xxx  xxx  xxx  xxx  xxx  xxx
    ffree   st(0)
    ffree   st(1)
    ffree   st(2)
    ffree   st(3)
    ffree   st(4)
    ffree   st(5)
    ffree   st(6)
	finit
;    fldcw   [OldFPUCW]                  ; restore the FPU

GF3D_finish:			   
;    mov esp, [StackStore]
	popad
	ret

endif




_TEXT	ENDS

END
