;// asm1.asm

bits 32




;include "pmode.idl"
;include "macros.inc"

global _BILTAB

section .data

align 16

global dofproc_
global drawpinmapns_
global drawpinmap48_
global drawpinmaptex_
extern _screenbuf
extern _reciptab
extern _multab
extern _zmaptab1
extern _zmaptab2
extern _zmaptab3
extern _edgebuf

global _cval

global _linecol

global _cliptab

_cliptab:
cliptab:

%assign n 0
%rep 256
db n
%assign n n+1
%endrep

times 256 db 255

global _cliptab128
_cliptab128:
cliptab128:
%assign n 0
%rep 128
db n
%assign n n+1
%endrep
times 128 db (127)



global _miny
global _maxy
_miny dd 0
_maxy dd 0


drawn dd 0

yinc_c dd 0
xinc_c dd 0
yinc_u dd 0
ulo	dw 0
xinc_u dd 0
dw 0
yinc_v dd 0
xinc_v dd 0

vhi dd 0
uhi_vlo dd 0

line_c dd 0
line_u dd 0
line_v dd 0
line_edi dd 0

x1 dd 0
x2 dd 0
y1 dd 0
y2 dd 0

yinc dd 0
xinc dd 0
xstart dd 0
ystart dd 0
xcount dd 0
ycount dd 0
bmapwid dd 0
bmaphgt dd 0
bmapptr dd 0
destptr dd 0
edgetab times 512 dd (0)
spritetab times 256 db (0)


global pintexptr
pintexptr dd 0
%assign xsize 320

val1	dd 0
ival1	dd	0
yval1	dd	0
iebp	dd	0
yebp	dd	0
val2	db	0
ival2	db	0
val3	db	0
ival3	db	0
yval2	db	0
yval3	db	0
		db	0,0




align 16

section .text



align 16



;=========================================================================
; polygons!

global resetedges_
resetedges_:
		mov _miny,200
		mov _maxy,0
		ret
;;resetedges_ endp

;addedge_ proc
addedge_:
		push esi
		push edi
		push ebp
		push ebx
		push ecx
		; line eax,edx to ebx,ecx
		mov edi,_edgebuf+4
		sub ebx,eax
		sub ecx,edx
		je forgetit
		jg down
		add eax,ebx
		add edx,ecx
		neg ebx
		neg ecx
		sub edi,4
down:
		cmp edx,200
		jge forgetit
		lea ebp,[ecx+edx]
		or ebp,ebp
		jle forgetit
		shl eax,16
		mov esi,[_reciptab+ecx*4+1024*4]
		imul ebx,esi

		; eax = x, ebx = dx, edx=y1, ebp=y2, ecx=ycount
		or edx,edx
		jge notop
		; top clip
		add ecx,edx
		jle forgetit
		imul edx,ebx
		sub eax,edx
		xor edx,edx
notop:  sub ebp,200
		jle nobottom
		sub ecx,ebp
		jle forgetit
nobottom:
		; eax = x, ebx = dx, edx=y1, ecx=ycount

		add ebp,200
		;.if ebp>_maxy
		cmp ebp,[_maxy]
		jle skip1
		mov _maxy,ebp
skip1:
		;.endif
		;.if edx<_miny
		cmp edx,[_miny]
		jge skip2
		mov _miny,edx
skip2:
		;.endif

		xor ebp,ebp
		mov esi,320*65536
		lea edi,[edi+edx*8]
		or ebx,ebx
		jle left
right:
		or eax,eax
		jle roffl
rloop1:
		cmp eax,esi
		jge roffr
		mov [edi],eax
		add edi,8
		add eax,ebx
rjumpback:
		dec ecx
		jnz rloop1
		jmp forgetit
roffl:
		mov [edi],ebp	; 0
		add edi,8
		add eax,ebx
		jg  rjumpback
		dec ecx
		jnz roffl
		jmp forgetit
roffr:
		mov [edi],esi ; 320*65536
		add edi,8
		dec ecx
		jnz roffr
		jmp forgetit

left:
		cmp eax,esi
		jge loffr
lloop1:
		or eax,eax
		jle loffl
		mov [edi],eax
		add edi,8
		add eax,ebx
ljumpback:
		dec ecx
		jnz lloop1
		jmp forgetit
loffr:
		mov [edi],esi ; 320
		add edi,8
		add eax,ebx
		cmp eax,esi
		jl  ljumpback
		dec ecx
		jnz loffr
		jmp forgetit
loffl:
		mov [edi],ebp ; 0
		add edi,8
		dec ecx
		jnz loffl

forgetit:
		pop edx	;; pop end point into start point...
		pop eax
		pop ebp
		pop edi
		pop esi
		ret
;;addedge_ endp






; triangle
global addedge_
global flattri_
global flatquad_
global flatfill_
global checkfill_
global texgoufill_
global gouraudfill_



%macro calccmac	0
	mov	eax,[esi+8+0]
	mov	ebx,[esi+16+4]
	sub	eax,[esi+0]			; x1
	sub	ebx,[esi+8+4]   	; y2
	mov x1,eax
	mov y2,ebx
	imul	ebx
	mov	ebx,[esi+8+4]
	mov	edx,[esi+16+0]
	sub	ebx,[esi+4]  		; y1
	sub	edx,[esi+8+0] 		; x2
	mov y1,ebx
	mov x2,edx
	imul	ebx,edx
	sub	eax,ebx
	jle	pforgetit
	mov _cval,eax
%endm


%macro calcincr	3 ; macro ecxofs,suffix,adjust
		mov	eax,[ecx+4+%1]
		sub	eax,[ecx+%1]			; z1
		imul	eax,x2
		mov	edx,[ecx+8+%1]
		sub	edx,[ecx+4+%1] 		; z2
		imul	edx,x1
		sub	eax,edx
		neg eax
		;;;;; fix up for big divs
		cmp eax,32767
		jge %%toobig1%2
		cmp eax,-32768
		jle %%toobig1%2
		;;;;;
		cdq
		shld edx,eax,16
		shl eax,16
		idiv _cval
%%toobig1a%2:
		mov yinc%2,eax

		mov	eax,[ecx+8+%1]
		sub	eax,[ecx+4+%1]			; z2
		imul	eax,y1
		mov	edx,[ecx+4+%1]
		sub	edx,[ecx+0+%1] 		; z1
		imul	edx,y2
		sub	eax,edx
		neg eax
		;;;;; fix up for big divs
		cmp eax,32767
		jge %%toobig2%2
		cmp eax,-32768
		jle %%toobig2%2
		;;;;;
		cdq
		shld edx,eax,16
		shl eax,16
		idiv _cval
%%toobig2a%2:
		mov xinc%2,eax

		; compute d
		imul eax,[ebp] 	; x1
		mov ebp,[ebp+4]	; y1

;if %3 eq 1
		;sub eax,xinc%2	; %3 x and y by 1 pixel
		;dec ebp
;endif

		imul ebp,yinc%2
		add ebp,eax
		mov eax,[ecx+%1]
		neg ebp
		shl eax,16
		add ebp,eax

		; need to do ebp += yinc * esi and esi=edgebuf+esi*8
		mov eax,yinc%2
		imul eax,esi

;if %3 eq 1
%if %3 = 1
		add ebp,xinc%2	; %3 x by 1
%endif	
;endif


		add ebp,32768		; %3 up by 1/2 (rounding)

		add ebp,eax


%endm

%macro calcincrsub 1
toobig1%1:
		cdq
		shld edx,eax,12
		shl eax,12
		idiv _cval
		shl eax,4
		jmp toobig1a%1
toobig2%1:
		cdq
		shld edx,eax,12
		shl eax,12
		idiv _cval
		shl eax,4
		jmp toobig2a%1
		%endm

extern _texptr
extern _fadeptr
extern _ghostptr

texgoufill_:; dest, pts
		pushad
		mov val1,ebx ; source pts (first x,y used only)
		mov ebx,eax	; dest
		mov ecx,edx ; pts
		mov esi,_miny
		mov edx,_maxy
		sub edx,esi
		jle xforgetit
		lea edi,[esi*4+esi]
		shl edi,6
		add ebx,edi
		sub ebx,2
		mov line_edi,ebx

		; calc increments

		push edx

		mov ebp,val1
		calcincr 12,_u,1
		mov line_u,ebp
		mov ebp,val1
		calcincr 24,_v,1
		mov line_v,ebp
		mov ebp,val1
		calcincr 0,_c,0
		mov line_c,ebp

		mov eax,xinc_u
		cdq
		sar eax,16
		mov ecx,xinc_v
		shl ecx,16
		add eax,ecx
		mov uhi_vlo,eax
		mov eax,xinc_v
		adc edx,0
		sar eax,16
		add eax,edx

		mov [vhi],eax
		pop edx



		; work out the line values

		lea esi,[_edgebuf+esi*8]

		%define count [esp]
lineloop:
		mov edi,[esi]
		mov ecx,[esi+4]
		shr edi,16
		shr ecx,16
		sub ecx,edi
		jle nextline

		push	esi
		push	edx
		push	ecx		; count on stack

		mov		ebx,_texptr

		mov		ecx,xinc_v
		imul	ecx,edi
		add		ecx,line_v
		rol		ecx,16
		mov		bh,cl		; set up v: ecx, ebx

		mov		eax,xinc_u
		imul	eax,edi
		add		eax,line_u
		rol		eax,16
		mov		cl,al
		xor		al,al
		mov		esi,eax	; set up u (esi, cl)

		mov		eax,_fadeptr
		mov		edx,xinc_c
		imul	edx,edi
		add		edx,line_c
		rol		edx,16
		mov		ah,dl
		mov		ebp,xinc_c
		shl		ebp,16		; set up colour: ebp, eax, edx, ch
		mov		ch,xinc_c+2

		add		edi,line_edi ; set up edi



		; eax = |   table | col | tmp |
		; ebx = | texture | vhi | tmp |
		; ecx = |    v lo |dchi | uhi |
		; edx = |  col lo |  output   |
		; esi = |    u lo |  odd flag |
		; ebp = | dcol lo |           |
		; edi = | destination pointer |
		; increment variables: ulo, vhi, uhi_vlo, count. pref, stored on stack!!

		test edi,1
		jnz notodd
		; plot one odd pixel
		mov		bl,cl			; v		load ebx for read
		add		edx,ebp			; u 	ebp=colinclo. update col lo
		mov		al,[ebx]		; v		read texel
		adc		ah,ch			; u		ch=colinchi update col hi
		add		esi,ulo			; v		update u lo.
		adc		ecx,uhi_vlo		; u		update uhi / vlo
		mov		dl,[eax]		; v		look up the colour (note col is inced)
		adc		bh,vhi			; u		update vhi

		;mov dl,cl ;****************

		mov		[edi+2],dl
		dec		count
		jz		doneline
		inc		edi
notodd:
		; plot in pairs
		shr		count,1
		jz		mustdraw1
		adc		esi,0	;	flag esi if odd pixel
xloop:
		mov		bl,cl			; v		load ebx for read
		add		edx,ebp			; u 	ebp=colinclo. update col lo
		mov		al,[ebx]		; v		read texel
		adc		ah,ch			; u		ch=colinchi update col hi
		add		esi,ulo			; v		update u lo.
		adc		ecx,uhi_vlo		; u		update uhi / vlo
		mov		dl,[eax]		; v		look up the colour (note col is inced)
		;mov dl,bh ;****************
		adc		bh,vhi			; u		update vhi

		mov		bl,cl		    ; v		load ebx for NEXT read
		add		edx,ebp			; u 	ebp=colinclo. update col lo
		mov		al,[ebx]		; v		read texel
		adc		ah,ch			; u		ch=colinchi update col hi
		add		esi,ulo			; v		update u lo
		adc		ecx,uhi_vlo		; u		update uhi / vlo
		mov		dh,[eax]		; v		look up the colour (note col is inced)
		;mov dh,bh ;****************
		adc		bh,vhi			; u		update vhi

		add		edi,2			;
		dec		count			; 		decrement count
		mov		[edi],dx
		jnz		xloop
		;------------------------------------

		test	esi,1
		jz		doneline
mustdraw1:
		; plot last pixel
		mov		bl,cl			; v		load ebx for read
		add		edx,ebp			; u 	ebp=colinclo. update col lo
		mov		al,[ebx]		; v		read texel
		adc		ah,ch			; u		ch=colinchi update col hi
		mov		dl,[eax]		; v		look up the colour (note col is inced)

		;mov dl,bh ;****************
		mov		[edi+2],dl

doneline:
		pop		ecx
		pop		edx
		pop		esi

nextline:
		dec edx
		jz xforgetit
		add esi,8			; move on scan list
		add line_edi,320	; move on dest ptr
		mov eax,yinc_u
		mov	ebx,yinc_v
		mov ecx,yinc_c
		add line_u,eax
		add line_v,ebx
		add line_c,ecx
		jmp lineloop


xforgetit:
		popad
		ret

		calcincrsub _c
		calcincrsub _u
		calcincrsub _v

;texgoufill_ endp



gouraudfill_: ; dest, pts
		pushad
		mov ebp,ebx ; source pts (first x,y used only)
		mov ebx,eax	; dest
		mov ecx,edx ; pts
		mov esi,_miny
		mov edx,_maxy
		sub edx,esi
		jle yforgetit
		lea edi,[esi*4+esi]
		shl edi,6
		add ebx,edi

		; calc increments

		push edx
		calcincr 0,_c,1
		pop edx

		lea esi,_edgebuf[esi*8]

lineloop:
		; ebp stores col value for start of line
		push ebp
		push ebx
		push edx
		mov edi,[esi]
		mov ecx,[esi+4]
		shr edi,16
		shr ecx,16
		sub ecx,edi
		jle nextline


		; need to do ebp += (edx=xinc) * edi

		mov edx,xinc_c
		mov eax,edx
		imul eax,edi
		add ebp,eax

		; need edi = dest, ebp:bl = col, edx:bh = col inc, ecx = count

		lea edi,[ebx+edi]
		shld ebx,ebp,16
		rol edx,16
		shl ebp,16
		mov bh,dl

		mov eax,[edi+3]	; fill the cache...
		test edi,1			; line up to dword boundary
		jz notodd
		dec ecx
		mov [edi],bl
		jz nextline
		add ebp,edx
		inc edi
		adc bl,bh
notodd:
		test edi,2
		jz notodd2
		dec ecx
		mov [edi],bl
		jz nextline
		add ebp,edx
		inc edi
		adc bl,bh
		dec ecx
		mov [edi],bl
		jz nextline
		add ebp,edx
		inc edi
		adc bl,bh
notodd2:
		push ecx
		mov eax,[edi+60]	; fill the cache...
		shr ecx,2
		jz endbit
pixloop:					; plot groups of 4
		repeat 2
		mov al,bl
		add ebp,edx
		adc bl,bh
		mov ah,bl
		add ebp,edx
		adc bl,bh
		rol eax,16
		endm
		mov [edi],eax
		add edi,4
		dec ecx
		jnz pixloop
endbit:
		pop ecx
		and ecx,3
		jz nextline
		dec ecx
		mov [edi],bl		;; plot the remaining (up to) 3 pixels
		jz nextline
		add ebp,edx
		adc bl,bh
		dec ecx
		mov [edi+1],bl
		jz nextline
		add ebp,edx
		adc bl,bh
		mov [edi+2],bl
nextline:
		pop edx
		pop ebx
		pop ebp
		add ebp,yinc_c
		add esi,8
		add ebx,320
		dec edx
		jnz lineloop
yforgetit:
		popad
		ret
calcincrsub _c

;gouraudfill_ endp


flattri_: ; dest, poly, col
		push esi
		push eax	; dest
		push ebx	; col
		mov esi,edx

		calccmac

		mov _miny,200
		mov _maxy,0
		mov eax,[esi]
		mov edx,[esi+4]
		mov ebx,[esi+8]
		mov ecx,[esi+12]
		call addedge_
		mov ebx,[esi+16]
		mov ecx,[esi+20]
		call addedge_
		mov ebx,[esi+0]
		mov ecx,[esi+4]
		call addedge_

		pop edx
		pop eax
		pop esi
		jmp flatfill_
pforgetit::
		pop edx
		pop esi ; dont touch eax
		pop esi
_ret::
		ret
;flattri_ endp

flatquad_: ; dest, poly, col
		push esi
		push eax	; dest
		push ebx	; col
		mov esi,edx

		calccmac

		mov _miny,200
		mov _maxy,0
		mov eax,[esi]
		mov edx,[esi+4]
		mov ebx,[esi+8]
		mov ecx,[esi+12]
		call addedge_
		mov ebx,[esi+16]
		mov ecx,[esi+20]
		call addedge_
		mov ebx,[esi+24]
		mov ecx,[esi+28]
		call addedge_
		mov ebx,[esi+0]
		mov ecx,[esi+4]
		call addedge_

		pop edx
		pop eax
		pop esi
		;jmp flatfill
		; fall thru
;flatquad_ endp

; flat fill
flatfill_: ; dest,col
		or eax,eax
		jz goaway
		pushad
		mov dh,dl
		mov ebx,eax	; dest
		mov eax,edx ; col
		shl edx,16
		or  eax,edx
		mov esi,_miny
		mov edx,_maxy
		sub edx,esi
		jle forgetit2
		lea edi,[esi*4+esi]
		shl edi,6
		add ebx,edi
		lea esi,_edgebuf[esi*8]
lineloop:
		mov edi,[esi]
		mov ecx,[esi+4]
		shr edi,16
		shr ecx,16
		sub ecx,edi
		jle nextline
		lea edi,[ebx+edi]
		mov ebp,[edi+3]	; fill the cache...

		test edi,1
		jz notodd
		dec ecx
		mov [edi],al
		jz nextline
		inc edi
notodd: test edi,2
		jz notodd2
		dec ecx
		mov [edi],al
		jz nextline
		inc edi
		dec ecx
		mov [edi],al
		jz nextline
		inc edi
notodd2:
		mov ebp,[edi+60]	 ; fill the cache some more
		mov ebp,ecx
		shr ecx,2
		rep stosd
		mov ecx,ebp
		and ecx,3
		rep stosb
nextline:
		add esi,8
		add ebx,320
		dec edx
		jnz lineloop
forgetit:
		popad
goaway:
		mov eax,_cval
		ret
forgetit2:
		popad
		mov eax,-1
		ret

;flatfill_ endp

; check fill
checkfill_: ; dest,col
		or eax,eax
		jz goaway
		pushad
		mov dh,dl
		mov ebx,eax	; dest
		mov eax,edx ; col
		shl edx,16
		or  eax,edx
		mov esi,_miny
		mov edx,_maxy
		sub edx,esi
		jle forgetit2
		mov drawn,0
		lea edi,[esi*4+esi]
		shl edi,6
		add ebx,edi
		lea esi,_edgebuf[esi*8]
lineloop:
		mov edi,[esi]
		mov ecx,[esi+4]
		shr edi,16
		shr ecx,16
		sub ecx,edi
		jle nextline
		lea edi,[ebx+edi]

pixloop:
		cmp byte ptr [edi],0
		jne skipit
		inc drawn
		mov [edi],al
skipit:
		inc edi
		dec ecx
		jnz pixloop

nextline:
		add esi,8
		add ebx,320
		dec edx
		jnz lineloop
forgetit:
		popad
		mov eax,drawn
		ret


goaway:
		mov eax,-1
		ret
forgetit2:
		popad
		mov eax,-1
		ret

;checkfill_ endp



;=========================================================================
; focus stuff

pixwork macro leftsub,rightadd
		if rightadd eq 1
		  add bl,[esi-640+2]
		  adc bh,0
		  add bl,[esi-320+3]
		  adc bh,0
		  add bl,[esi+3]
		  adc bh,0
		  add bl,[esi+320+3]
		  adc bh,0
		  add bl,[esi+640+2]
		  adc bh,0
		endif
		if leftsub eq 1
		  sub bl,[esi-640-1]
		  sbb bh,0
		  sub bl,[esi-320-2]
		  sbb bh,0
		  sub bl,[esi-2]
		  sbb bh,0
		  sub bl,[esi+320-2]
		  sbb bh,0
		  sub bl,[esi+640-1]
		  sbb bh,0
		endif
		inc esi
		endm

pixmac macro leftsub,rightadd,leftsub2,rightadd2
		mov al,divide21[ebx]
		pixwork leftsub,rightadd
		mov ah,divide21[ebx]
		pixwork leftsub2,rightadd2
		mov [edi],ax
		inc edi
		inc edi
	   endm


global _blurproc


blurproc_:
		pushad
		mov esi,edx
		mov edi,eax
		add esi,320*2
		add edi,320*2
		mov ecx,195*256
lineloop:
		;  ***
		; *****
		; **!**
		; *****
		;  ***		; 21
		; line start - sum up the right half of the filter...
		xor ebx,ebx
		xor eax,eax
		mov bl,[esi-640]
		add bl,[esi-640+1]
		adc	bh,cl
		add bl,[esi-320+0]
		adc bh,cl
		add bl,[esi-320+1]
		adc bh,cl
		add bl,[esi-320+2]
		adc bh,cl
		add bl,[esi+0]
		adc bh,cl
		add bl,[esi+1]
		adc bh,cl
		add bl,[esi+2]
		adc bh,cl
		add bl,[esi+320+0]
		adc bh,cl
		add bl,[esi+320+1]
		adc bh,cl
		add bl,[esi+320+2]
		adc bh,cl
		add bl,[esi+640+0]
		adc bh,cl
		add bl,[esi+640+1]
		adc bh,cl
		; first 2 pixels are special
		pixmac 0,1,1,1
		; next 320-6 pixels are normal
		mov cl,(320-6)/2
xloop:  pixmac 1,1,1,1
		dec cl
		jnz xloop
		pixmac 1,0,1,0
		; next line please...
		inc edi
		inc esi
		inc edi
		inc esi
		dec ch
		jnz lineloop
		popad
		ret
;blurproc_ endp

blendmac macro dest,ofs
		mov al,[esi+ofs]
		mov bl,_zmaptab1[eax]
		mov bh,[ebp+ofs]
		mov dest,[ebx]
		mov bl,_zmaptab2[eax]
		mov bh,[ebp+ofs+64000]
		add dest,[ebx]
		mov bl,_zmaptab3[eax]
		mov bh,[ebp+ofs+128000]
		add dest,[ebx]

		endm

blendproc_:; proc
		pushad
		mov edi,eax ; dest
		mov esi,edx ; zbuffer
		mov ebp,ebx ; 3 blurred screens
		mov ebx,_multab ; mul tab (64k)
		xor eax,eax
		xor edx,edx

		add esi,4*320
		add edi,4*320
		add ebp,4*320
		mov ecx,(200-8)*80
pixloop:
		blendmac dl,2
		blendmac dh,3
		shl edx,16
		blendmac dl,0
		blendmac dh,1
		add esi,4
		add ebp,4
		mov [edi],edx
		add edi,4

		dec ecx
		jnz pixloop
		popad
		ret
;blendproc_ endp









;/////////////////
; anti aliased line... oh god

global unclippedline_
unclippedline_:
		pushad
		; line eax,edx to ebx,ecx
		sub ebx,eax
		sub ecx,edx
		jge down
		add eax,ebx
		add edx,ecx
		neg ebx
		neg ecx
down:
		test ebx,ebx
		jz zero
		jg posa
		neg ebx
		cmp ebx,ecx
		jge leftwards
		neg ebx
		jmp downwards
zero:
		test ecx,ecx
		jz doneit
posa:
		cmp ebx,ecx
		jge rightwards
downwards:
		; line is mostly downwards
		shl eax,16
		lea esi,[edx*4+edx]	; esi=screenmem
		shl esi,6
		add esi,_screenbuf
		mov ebp,_reciptab[ecx*4+1024*4]
		imul ebp,ebx

		or ecx,ecx
		jle doneit
		; eax=x, ebp=xinc, esi=screenmem, ecx=count
		xor ebx,ebx
		mov edx,_multab
		mov dh,_linecol
loop1:
		; plot 2 pixels

		mov dl,ah

		; calc edi here
		mov edi,eax
		shr edi,16
		add edi,esi

		not dl
		mov bl,[edx]
		add bl,[edi]
		mov bl,cliptab128[ebx]
		mov [edi],bl

		mov dl,ah
		mov bl,[edx]
		add bl,[edi+1]
		mov bl,cliptab128[ebx]
		mov [edi+1],bl
		add eax,ebp
		add esi,320
		dec ecx
		jnz loop1
		jmp doneit

leftwards:
		; ebx already negged.
		sub eax,ebx
		add edx,ecx
		neg ecx
rightwards:
		; mostly rightwards

		xchg ebx,ecx
		xchg eax,edx
		shl eax,16
		mov esi,edx
		add esi,_screenbuf
		mov ebp,_reciptab[ecx*4+1024*4]
		imul ebp,ebx

		or ecx,ecx
		jle doneit
		; eax=y, ebp=yinc, esi=screenmem, ecx=count
		xor ebx,ebx
		mov edx,_multab
		mov dh,_linecol
loop2:
		; plot 2 pixels

		mov dl,ah

		; calc edi here
		mov edi,eax
		shr edi,16
		lea edi,[edi*4+edi]	; esi=screenmem
		shl edi,6
		add edi,esi

		not dl
		mov bl,[edx]
		add bl,[edi]
		mov bl,cliptab128[ebx]
		mov [edi],bl

		mov dl,ah
		mov bl,[edx]
		add bl,[edi+320]
		mov bl,cliptab128[ebx]
		mov [edi+320],bl
		add eax,ebp
		inc esi
		dec ecx
		jnz loop2

doneit:
		popad
		ret

;unclippedline_ endp







;///////////////////////////////////////////////////////////////////////
;// blur routines

;extern void hblur(SLONG bmapwid, SLONG blurwid,
;				  SLONG numdwords, SLONG numlines,
;				  UBYTE *texture, UBYTE *dest,
;				  UBYTE *fadetab,SLONG fadeinc, SLONG sizeoffadetab);
;hblur(320,
;abs(c1)+1,320/4,54,src,dest,myfadetab,(65536-(abs(c1))*1000)/(abs(c1)+1),16384);

global hblur_
hblur_:
		pushad

		mov ebp,eax
		;mov edx,edx
		mov al,bl
		mov ah,cl
		mov ecx,ebp
		mov esi,[esp+36]
		mov edi,[esp+40]
		mov ebp,[esp+44]

		xor ebx,ebx
fillloop:
		rol ebx,16
		mov [ebp],bl
		rol ebx,16
		add ebx,[esp+48]
		cmp ebx,256*65536
		jl ok1
		mov ebx,256*65536-1
ok1:
		inc ebp
		dec dword [esp+52]
		jnz fillloop
		mov ebp,[esp+44]

		; ecx = width of bitmap
		; edx = blur width
		; al  = number of dwords per line to draw
		; ah  = number of lines
		; esi = bitmap pointer (pad w 0s to left and right)
		; edi = dest screen
		; ebp = 1 line fade table

lineloop:
		push ecx
		push esi
		mov ecx,edx
		shr ecx,1
		sub esi,ecx

		mov ecx,edx
		xor ebx,ebx
startloop:
		add bl,[esi]
		inc esi
		adc bh,0
		dec ecx
		jnz startloop
		; ch is now 0
		sub esi,edx
		push edi
		push eax
		mov cl,al

pixloop:
		mov	al,[ebx+ebp]
		add bl,[esi+edx]
		adc bh,ch
		sub bl,[esi]
		sbb bh,ch
		mov	ah,[ebx+ebp]
		add bl,[esi+edx+1]
		adc bh,ch
		sub bl,[esi+1]
		sbb bh,ch
		rol eax,16
		mov	al,[ebx+ebp]
		add bl,[esi+edx+2]
		adc bh,ch
		sub bl,[esi+2]
		sbb bh,ch
		mov	ah,[ebx+ebp]
		add bl,[esi+edx+3]
		adc bh,ch
		sub bl,[esi+3]
		sbb bh,ch
		rol eax,16
		mov	[edi],eax
		add edi,4
		add esi,4
		dec cl
		jnz pixloop
np:
		pop eax
		pop edi
		pop esi
		pop ecx
		add edi,12345678h
		org $-4
blurwid dword 320
		add esi,ecx
		dec ah
		jnz lineloop
		popad
		ret 5*4
;hblur_	endp

global setblurwid_
setblurwid_:
		mov	ds:[blurwid],eax
		ret
;setblurwid_ endp



;///////////////////////////////////////////////////////////////////////////////////////////////////////
; unshaded pin mapper

pin struct
u	dword	?
v	dword	?
col dword	?
pin ends

extern _pin



;bl:edx :edx contains u and lo v, bl contains hi v
;val2:val1 contains u/v incs
;ch:esi contains colour
;val3:ebp contains colour inc
;ival1,ival2,ival3,iebp are delta deltas

pinmapnsmacro macro WIDTH,HEIGHT,adjust

			pushad
			mov	esi,offset _pin
			mov edi,edx
			mov pintexptr,eax

			mov ch,HEIGHT
pinyloop:
			mov cl,WIDTH
pinxloop:
			assume esi:ptr pin
			push esi
			push ecx
			mov eax,[esi+sizeof pin].u
			sub eax,[esi].u
			mov edx,[esi+(sizeof pin)*(WIDTH+2)].u
			sub edx,[esi+(sizeof pin)*(WIDTH+1)].u
			sub edx,eax
			sar eax,3
			sar edx,6+adjust
			mov ebp,eax
			sar eax,31
			mov cl,al
			mov ival1,edx
			sar edx,31
			mov ival2,dl
			mov eax,[esi+(sizeof pin)*(WIDTH+1)].u
			sub eax,[esi].u
			sar eax,3+adjust
			mov yval1,eax
			sar eax,31
			mov yval2,al

			mov eax,[esi+sizeof pin].v
			sub eax,[esi].v
			mov edx,[esi+(sizeof pin)*(WIDTH+2)].v
			sub edx,[esi+(sizeof pin)*(WIDTH+1)].v
			sub edx,eax
			sar eax,3
			sar edx,6+adjust
			add cl,ah
			shl eax,24
			add ebp,eax
			adc cl,0
			add ival2,dh
			shl edx,24
			add ival1,edx
			adc ival2,0
			mov eax,[esi+(sizeof pin)*(WIDTH+1)].v
			sub eax,[esi].v
			sar eax,3+adjust
			add yval2,ah
			shl eax,24
			add yval1,eax
			adc yval2,0

			mov ebx,pintexptr
			mov dl,byte ptr ([esi].v)
			shl edx,24
			add edx,800000h
			mov eax,[esi].u
			and eax,65535
			add edx,eax
			mov bl,byte ptr ([esi].v)+1

;bl:edx :edx contains u and lo v, bl contains hi v
;ebp:cl contains u/v incs
;ch counter
;ival1,ival2 are delta deltas



			mov	ch,8 shl adjust
again:
			push	edx
			push	ebx

	;comment !
			mov bh,dh         ; u
			add edx,ebp      ; v
			mov al,[ebx]      ; u
			mov bh,dh		; v
			adc bl,cl		;  u

			add edx,ebp      ; v
			mov ah,[ebx]      ; u
			mov bh,dh         ;  v
			adc bl,cl		;  u
			rol eax,16		; v

			add edx,ebp      ; u
			mov al,[ebx]      ; v
			adc bl,cl		;  u
			mov bh,dh         ; v

			add edx,ebp      ; u
			mov ah,[ebx]      ; v
			adc bl,cl		;  u
			rol eax,16		; v
			mov [edi],eax	; u

			;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

			mov bh,dh         ; u
			add edx,ebp      ; v
			mov al,[ebx]      ; u
			mov bh,dh		; v
			adc bl,cl		;  u

			add edx,ebp      ; v
			mov ah,[ebx]      ; u
			mov bh,dh         ;  v
			adc bl,cl		;  u
			rol eax,16		; v

			add edx,ebp      ; u
			mov al,[ebx]      ; v
			adc bl,cl		;  u
			mov bh,dh         ; v

			add edx,ebp      ; u
			mov ah,[ebx]      ; v
			adc bl,cl		;  u
			rol eax,16		; v
			mov [edi+4],eax	; u
;!
			pop ebx
			pop edx

			mov eax,yval1
			mov bh,yval2
			add edx,eax
			adc bl,bh


			mov eax,ival1	; v
			mov bh,ival2
			add ebp,eax	; v
			adc cl,bh       ; u
			add edi,WIDTH*8		  ; v
			dec ch			; u
			jnz again         ; v

			pop ecx
			pop esi
			add esi,sizeof pin
			sub	edi,WIDTH*8*(8 shl adjust)-8
			dec cl
			jnz pinxloop
			add esi,sizeof pin
			add edi,WIDTH*8*(8 shl adjust)-WIDTH*8
			dec ch
			jnz pinyloop
			assume esi:nothing

			popad
			ret
			endm

drawpinmapns_	proc
		; texture, destination
			pinmapnsmacro 40,25,0
;drawpinmapns_	endp

drawpinmaptex_	proc
		; texture, destination
			pinmapnsmacro 32,32,0
;drawpinmaptex_	endp

drawpinmap48_	proc
		; texture, destination
			pinmapnsmacro 40,30,1
;drawpinmap48_	endp


ghostcopy_:; proc
		gpixmac macro ofs
		mov bl,[esi+ofs]
		mov bh,[edi+ofs]
		mov cl,[esi+ofs+1]
		mov ch,[edi+ofs+1]
		mov al,[ebx]
		mov ah,[ecx]
		endm

		pushad
		mov edi,eax
		mov esi,edx
		mov ebx,_ghostptr
		mov ebp,64000/4
		mov ecx,ebx
again:
		gpixmac 2
		shl eax,16
		gpixmac 0
		add esi,4
		mov [edi],eax
		add edi,4
		dec ebp
		jnz again
		popad
		ret
;ghostcopy_ endp

extern _noisetab2
global ghostcopy_ 
global quantum_ 

quantum_:
		pushad
		mov edi,eax
		mov esi,edx
		mov ebp,ebx

		EBXVAL=01020201h
		EDXVAL=02040402h
	;	EDXVAL=02040402h
	;	EBXVAL=01020201h

		XXX = 1
		YYY = 07f7f7f7fh

		mov ecx,320*200/8
floop:  mov eax,[edi]
		mov ebx,[edi+4]
		shr eax,XXX
		shr ebx,XXX
		and eax,YYY
		and ebx,YYY
		mov [edi],eax
		mov [edi+4],ebx
		add edi,8
		dec ecx
		jnz floop
		sub edi,320*200

		mov ebx,EBXVAL
		mov edx,EDXVAL

		ADDMAC macro ofs
		local nope
		jbe nope
		add [edi+ofs+  0],ebx
		add [edi+ofs+320],edx
		add [edi+ofs+640],edx
		add [edi+ofs+960],ebx
nope:
		endm


		mov ch,200-4
yloop:
		mov cl,320/4-1
xloop:
		mov	eax,[esi]
		;shr eax,2
		;and eax,3f3f3f3fh

		and ebp,NOISETABSIZE-1
		cmp al,_noisetab2[ebp]
		ADDMAC 0
		cmp ah,_noisetab2[ebp+1]
		ADDMAC 1
		shr eax,16
		cmp al,_noisetab2[ebp+2]
		ADDMAC 2
		cmp ah,_noisetab2[ebp+3]
		ADDMAC 3

		; clipping pass
		mov eax,[edi]
		xor ebx,ebx
		mov bl,al
		mov al,cliptab128[ebx]
		mov bl,ah
		mov ah,cliptab128[ebx]
		rol eax,16
		mov bl,al
		mov al,cliptab128[ebx]
		mov bl,ah
		mov ah,cliptab128[ebx]
		rol eax,16
		mov ebx,EBXVAL
		mov [edi],eax

		add ebp,4
		add edi,4
		add esi,4
		dec cl
		jnz xloop
		mov dword [edi],0
		add edi,4
		add esi,4

extern rand_

		dec ch
		jz donet
		test ch,7
		jnz yloop
		call rand_
		mov ebp,eax
		jmp yloop
donet:

		popad
		ret
quantum_ endp







global noisefade_ 
extern _noisetab

NOISETABSIZE = 4096
noisefade_ proc
		pushad
		; dest/src, yshades, randseed
		mov esi,eax
		mov ebp,ebx
		mov edi,edx

		mov ebx,_fadeptr
		push 200
yloop:
		mov ch,[edi]
		mov cl,80
		inc edi
xloop:
		and ebp,NOISETABSIZE-1
		mov bh,_noisetab[ebp]
		add bh,ch
		mov bl,[esi+2]
		mov al,[ebx]
		mov bh,_noisetab[ebp+1]
		add bh,ch
		mov bl,[esi+3]
		mov ah,[ebx]
		shl eax,16
		mov bh,_noisetab[ebp+2]
		add bh,ch
		mov bl,[esi]
		mov al,[ebx]
		mov bh,_noisetab[ebp+3]
		add bh,ch
		mov bl,[esi+1]
		mov ah,[ebx]
		add ebp,4
		mov [esi],eax
		add esi,4
		dec cl
		jnz xloop
		dec byte ptr [esp]
		jnz yloop
		pop eax
		popad
		ret
noisefade_ endp



blurfade_ proc
		pixmac macro ofs
		mov al,[esi+ofs-1]
		add al,[esi+ofs+1]
		add al,[esi+ofs+320]
		adc ah,bl
		add al,[esi+ofs-320]
		adc ah,bl
		add al,[esi+ofs]
		adc ah,bl
		shr eax,3
		endm

		pushad
		mov edi,eax
		mov esi,edx
		xor ebx,ebx
		xor eax,eax

		mov ecx,320*200/4
again:
		pixmac 2
		mov dl,al
		pixmac 3
		mov dh,al
		shl edx,16
		pixmac 0
		mov dl,al
		pixmac 1
		mov dh,al
		mov [edi],edx
		add esi,4
		add edi,4
		dec ecx
		jnz again
		popad
		ret
blurfade_ endp

global blurfade_

;===================================================================================

; x1,y1,x2,y2, dest, bmpwid, bmphgt, bmpptr, col
scalespr_ proc
		pushad
		push eax
		mov eax,[esp+36+4]
		mov destptr,eax
		mov eax,[esp+40+4]
		mov bmapwid,eax
		mov eax,[esp+44+4]
		mov bmaphgt,eax
		mov eax,[esp+48+4]
		mov bmapptr,eax
		mov edi,offset spritetab
		mov esi,256
		xor eax,eax
sprloop:
		mov [edi],ah
		inc edi
		add eax,[esp+52+4]
		.if eax>=128*256
		mov eax,7fffh
		.endif
		dec esi
		jnz sprloop
		pop eax

		xchg edx,ebx

		;    x          y
		; eax,edx to ebx,ecx

		_xres = 320
		_yres = 200

		cmp eax,_xres
		jge forgetit
		or edx,edx
		jle forgetit
		cmp ebx,_yres
		jge forgetit
		or ecx,ecx
		jle forgetit

		sub edx,eax
		jle forgetit
		sub ecx,ebx
		jle forgetit
		push edx
		push eax
		mov ebp,edx
		xor edx,edx
		mov eax,65536
		imul eax,bmapwid
		div ebp
		mov xinc,eax
		xor edx,edx
		mov eax,65536
		imul eax,bmaphgt
		div ecx
		mov yinc,eax
		pop eax
		pop edx
		add edx,eax
		add ecx,ebx

		mov xstart,0
		mov ystart,0

		or eax,eax
		jge nc1
		imul eax,xinc
		neg eax
		mov xstart,eax
		xor eax,eax
nc1:	cmp edx,_xres
		jle nc2
		mov edx,_xres
nc2:	or ebx,ebx
		jge nc3
		imul ebx,yinc
		neg ebx
		mov ystart,ebx
		xor ebx,ebx
nc3:	cmp ecx,_yres
		jle nc4
		mov ecx,_yres
nc4:	sub edx,eax
		jle forgetit
		sub ecx,ebx
		jle forgetit

		mov xcount,edx
		mov ycount,ecx

		; build screen pointer
		imul ebx,_xres
		lea esi,[ebx+eax]
		add esi,destptr

		; build table
		mov ecx,xcount
		mov edi,offset edgetab
		mov eax,xstart
		mov ebp,xinc
tabloop:
		mov edx,eax
		sar edx,16
		mov [edi],edx
		and eax,65535
		add eax,ebp
		add edi,4
		dec ecx
		jnz tabloop

		;.esi = screen
		;.ebx = texture somehow
		;.edx = fadetable
		;.eax = scratch
		;.ebp = output colour buildup
		;.edi = table of ebx incs
		; ecx = x counter

		;mov edx,_fadetable
		xor edx,edx
lineloop:
		mov edi,offset edgetab
		mov ecx,xcount

		push esi

		mov ebx,ystart
		shr ebx,16
		imul ebx,bmapwid
		mov eax,yinc
		add ystart,eax
		add ebx,bmapptr

pixloop:
		add ebx,[edi]
		mov dl,[ebx]
		mov dl,spritetab[edx]
		add dl,[esi]
		mov al,cliptab128[edx]
		dec ecx
		jz  justal
		inc esi
		add edi,4

		add ebx,[edi]
		mov dl,[ebx]
		mov dl,spritetab[edx]
		add dl,[esi]
		mov ah,cliptab128[edx]
		add edi,4
		dec ecx
		mov [esi-1],ax
		jz	doneloop
		inc esi
		jmp pixloop
justal:
		mov [esi],al
doneloop:
		pop esi
		add esi,_xres
		dec ycount
		jnz lineloop
forgetit:
		popad
		ret 20
scalespr_ endp




;;----------------------------------------------------------------------

global compose_
compose_ proc
		pushad
		mov edi,eax
		mov esi,edx
		;mov ebx,ebx
		mov ecx,64000/4

again:
		mov edx,[esi]
		mov eax,[edi]
		mov bl,al
		mov bh,dl
		mov al,[ebx]
		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		rol edx,16
		mov bl,al
		mov bh,dl
		mov al,[ebx]
		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		add esi,4
		mov [edi],eax
		add edi,4
		dec ecx
		jnz again
		popad
		ret
compose_ endp

global composesil_
composesil_ proc
		pushad
		mov edi,eax
		mov esi,edx
		;mov ebx,ebx
		mov ecx,64000/4

again:
		mov edx,[esi]
		shr edx,2
		mov eax,[edi]
		and edx,3f3f3f3fh
		mov bl,al
		add edx,10101010h
		mov bh,dl
		mov al,[ebx]


		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		rol edx,16
		mov bl,al
		mov bh,dl
		mov al,[ebx]
		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		add esi,4
		mov [edi],eax
		add edi,4
		dec ecx
		jnz again
		popad
		ret
composesil_ endp


global composelight
composelight_ proc
		pushad
		mov edi,eax
		mov esi,edx
		;mov ebx,ebx
		mov ecx,64000/4

again:
		mov edx,[esi]
		shr edx,2
		mov eax,[edi]
		and edx,1f1f1f1fh
		mov bl,al
		add edx,30303030h
		mov bh,dl
		mov al,[ebx]
		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		rol edx,16
		mov bl,al
		mov bh,dl
		mov al,[ebx]
		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		add esi,4
		mov [edi],eax
		add edi,4
		dec ecx
		jnz again
		popad
		ret
composelight_ endp

externdef composedark:near
composedark_ proc
		pushad
		mov edi,eax
		mov esi,edx
		;mov ebx,ebx
		mov ecx,64000/4

again:
		mov edx,[esi]
		shr edx,2
		mov eax,[edi]
		and edx,1f1f1f1fh
		neg edx
		mov bl,al
		add edx,30303030h
		mov bh,dl
		mov al,[ebx]
		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		rol edx,16
		mov bl,al
		mov bh,dl
		mov al,[ebx]
		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		add esi,4
		mov [edi],eax
		add edi,4
		dec ecx
		jnz again
		popad
		ret
;composedark_ endp


externdef composelightdark:near
composelightdark_ proc
		pushad
		mov edi,eax
		mov esi,edx
		;mov ebx,ebx
		mov ecx,64000/4

again:
		mov edx,[esi]
		shr edx,1
		mov eax,[edi]
		and edx,3f3f3f3fh
		mov bl,al
		add edx,10101010h



		mov bh,dl
		mov al,[ebx]
		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		rol edx,16
		mov bl,al
		mov bh,dl
		mov al,[ebx]
		mov bl,ah
		mov bh,dh
		mov ah,[ebx]
		rol eax,16
		add esi,4
		mov [edi],eax
		add edi,4
		dec ecx
		jnz again
		popad
		ret
;composelightdark_ endp



end

