
; File:   poly_flat.s
; Author: Mikael Kalms <mikael@kalms.org>
; Date:   1 Oct 1999
; Title:  Single-coloured chunky polygon rasterizer
;
; Description:
;   Draws polygons consisting of N>=3 vertices, and no gradients
;   (single colour across the entire polygon)
;   Scissoring used for 2d clipping


FPOLYMAXVERTICES = 64

; in		d0	number of vertices
;		d1	colour
;		a0	vertices (x,y as 16:16 fixed point)
;		a1	screen

		section	code,code

fpolydrawclip_sub
		movem.l	d2-d7/a2-a6,-(sp)
		move.b	d1,d5		; Extend colour to all 4 bytes
		lsl.w	#8,d5
		move.b	d1,d5
		move.w	d5,d1
		swap	d5
		move.w	d1,d5

		lea	(a0,d0.w*8),a3

		move.l	4(a0),d1	; Find highest vertex
		move.l	a0,d2
		lea	8(a0),a2
.findlowest	cmp.l	4(a2),d1
		ble.s	.nnewlowest
		move.l	4(a2),d1
		move.l	a2,d2
.nnewlowest	addq.l	#8,a2
		cmp.l	a3,a2
		blo.s	.findlowest

		lea	newvertices,a6
		move.l	a6,a5

		move.l	d2,a2		; Copy/rotate vertexlist
.copy1		move.l	(a2)+,(a6)+
		move.l	(a2)+,(a6)+
		cmp.l	a3,a2
		blo.s	.copy1
.copy2		move.l	(a0)+,(a6)+
		move.l	(a0)+,(a6)+
		cmp.l	d2,a0
		bls.s	.copy2

		move.l	d5,a2

		subq.l	#8,a6

		swap	d1		; Adjust screenptr to first
		tst.w	d1		; potentially visible line of polygon
		spl	d2
		ext.w	d2
		and.w	d2,d1
		mulu.w	#CHUNKYXMAX,d1
		add.l	d1,a1

		moveq	#0,d6		; Both sides need new segments
		moveq	#0,d7

.segment
		cmp.l	a5,a6		; End of polygon?
		bls	.polydone

		tst.w	d6		; Update left side, if necessary
		bgt.s	.leftsegok
		move.l	4(a6),d1
		move.l	-(a6),d3
		subq.l	#4,a6
		move.l	d3,d6
		swap	d6
		move.l	d1,d0
		tst.w	d6
		ble.s	.segment
		swap	d0
		cmp.w	#CHUNKYYMAX,d6
		bls.s	.nleftclipymax
		move.w	#CHUNKYYMAX,d6
.nleftclipymax
		tst.w	d0
		spl	d2
		ext.w	d2
		and.w	d2,d0
		sub.w	d0,d6
		ble.s	.segment

		move.l	(a6),d2
		moveq	#12,d4
		move.l	8(a6),d0
		asr.l	d4,d1
		asr.l	d4,d3
		sub.l	d0,d2
		sub.l	d1,d3
		neg.l	d1
		add.l	#$f,d1
		bgt.s	.nleftclipxmax
		and.l	#$f,d1
.nleftclipxmax
		divs.l	d3,d2
		muls.l	d2,d1
		lsl.l	#4,d2
		move.l	d2,a3
		add.l	d1,d0
		move.l	d0,d4
.leftsegok

		tst.w	d7		; Update right side, if necessary
		bgt.s	.rightsegok
		move.l	4(a5),d1
		move.l	12(a5),d3
		addq.l	#8,a5
		move.l	d3,d7
		swap	d7
		move.l	d1,d0
		tst.w	d7
		ble.s	.segment
		swap	d0
		cmp.w	#CHUNKYYMAX,d7
		bls.s	.nrightclipymax
		move.w	#CHUNKYYMAX,d7
.nrightclipymax
		tst.w	d0
		spl	d2
		ext.w	d2
		and.w	d2,d0
		sub.w	d0,d7
		ble	.segment

		move.l	(a5),d2
		moveq	#12,d5
		move.l	-8(a5),d0
		asr.l	d5,d1
		asr.l	d5,d3
		sub.l	d0,d2
		sub.l	d1,d3
		neg.l	d1
		add.l	#$f,d1
		bgt.s	.nrightclipxmax
		and.l	#$f,d1
.nrightclipxmax
		divs.l	d3,d2
		muls.l	d2,d1
		lsl.l	#4,d2
		move.l	d2,a4
		add.l	d1,d0
		move.l	d0,d5
.rightsegok

		move.w	d6,d0
		cmp.w	d7,d0
		bls.s	.min
		move.w	d7,d0
.min
		sub.w	d0,d6
		sub.w	d0,d7
.line
		move.l	d0,-(sp)
		move.l	d4,d0
		move.l	d5,d1
		swap	d0
		swap	d1
		tst.w	d0
		bpl.s	.nclipleft
		moveq	#0,d0
.nclipleft	cmp.w	#CHUNKYXMAX,d1
		ble.s	.nclipright
		move.w	#CHUNKYXMAX,d1
.nclipright	cmp.w	d0,d1
		ble.s	.nline

		lea	(a1,d0.w),a0

		move.w	d0,d2
		move.w	d1,d3
		lsr.w	#2,d0
		not.w	d2
		lsr.w	#2,d1
		and.w	#$3,d2
		and.w	#$3,d3

		sub.w	d0,d1
		bne.s	.nsinglespan
		add.w	d3,d2
		moveq	#0,d3
		and.w	#$3,d2
.nsinglespan
		move.l	a2,d0
.firstspan	move.b	d0,(a0)+
		subq.w	#1,d2
		bpl.s	.firstspan

		subq.w	#1,d1
		ble.s	.nmiddlespans
.middlespans	move.l	a2,(a0)+
		subq.w	#1,d1
		bgt.s	.middlespans
.nmiddlespans
		tst.w	d1
		bmi.s	.nlastspan
		tst.w	d3
		ble.s	.nlastspan
.lastspan	move.b	d0,(a0)+
		subq.w	#1,d3
		bgt.s	.lastspan
.nlastspan

.nline
		move.l	(sp)+,d0
		add.w	#CHUNKYXMAX,a1
		add.l	a3,d4
		add.l	a4,d5
		subq.w	#1,d0
		bgt.s	.line

		bra	.segment

.polydone
		movem.l	(sp)+,d2-d7/a2-a6
		rts


		section	bss,bss

newvertices	ds.l	2*(FPOLYMAXVERTICES+1)
