
ma_Sizeof	equ	4

;---------------------------------------------------------------------
		XDEF		_TransPointRaw
		cnop		0,4
_TransPointRaw	;a0-Vector,a1-Vector,a2-ViewMatrix+Translate
;---------------------------------------------------------------------

		fmove.s		(a1),fp0
		fmove.s		4(a1),fp1
		fmove.s		8(a1),fp2
		fsub.s		36(a2),fp0
		fsub.s		40(a2),fp1
		fsub.s		44(a2),fp2
		bra.s		trans

;---------------------------------------------------------------------
		XDEF		_TransVector
		cnop		0,4
_TransVector	;a0-Vector,a1-Vector,a2-ViewMatrix
;---------------------------------------------------------------------

		fmove.s		(a1),fp0
		fmove.s		4(a1),fp1
		fmove.s		8(a1),fp2

trans		fmove		fp0,fp3
		fmul.s		(a2),fp3
		fmove		fp1,fp4
		fmul.s		4(a2),fp4
		fadd		fp3,fp4
		fmove		fp2,fp3
		fmul.s		8(a2),fp3
		fadd		fp4,fp3
		fmove.s		fp3,(a0)

		fmove		fp0,fp3
		fmul.s		24(a2),fp3
		fmove		fp1,fp4
		fmul.s		24+4(a2),fp4
		fadd		fp3,fp4
		fmove		fp2,fp3
		fmul.s		24+8(a2),fp3
		fadd		fp3,fp4
		fmove.s		fp4,4(a0)

		fmul.s		12(a2),fp0
		fmul.s		12+4(a2),fp1
		fadd		fp1,fp0
		fmul.s		12+8(a2),fp2
		fadd		fp2,fp0
		fmove.s		fp0,8(a0)

		rts


;---------------------------------------------------------------------
		XDEF		_TransPoint
		cnop		0,4
_TransPoint	;a0-Point_3D,a1-Vector,a2-ViewMatrix+Translate
;---------------------------------------------------------------------

		fmove.s		vc_X(a1),fp3
		fsub.s		36(a2),fp3	;temp.x
		fmove		fp3,fp6
		fmul.s		(a2),fp6

		fmove.s		vc_Y(a1),fp1
		fsub.s		40(a2),fp1	;temp.y
		fmove		fp1,fp4
		fmul.s		4(a2),fp4

		fmove.s		vc_Z(a1),fp2
		fsub.s		44(a2),fp2	;temp.z
		fmove		fp2,fp5
		fmul.s		8(a2),fp5

		fadd		fp5,fp6
		fadd		fp4,fp6
		fmove.s		fp6,po_X(a0)

		fmove		fp3,fp7
		fmul.s		24(a2),fp7
		fmove		fp1,fp4
		fmul.s		24+4(a2),fp4
		fmove		fp2,fp5
		fmul.s		24+8(a2),fp5
		fadd		fp5,fp7
		fadd		fp4,fp7
		fmove.s		fp7,po_Y(a0)

		fmul.s		12(a2),fp3
		fmul.s		12+4(a2),fp1
		fadd		fp1,fp3
		fmul.s		12+8(a2),fp2
		fadd		fp2,fp3
		fmove.s		fp3,po_Z(a0)

		moveq		#CC_BEHIND,d0

		fcmp.s		#$3c23d70a,fp3
		fbolt		.Skip

		fmove.s		#$47800000,fp0
		fdiv		fp3,fp0
		fmul		fp0,fp6
		fadd.s		_xcenter2,fp6
		fmul		fp0,fp7
		fneg		fp7
		fadd.s		_ycenter2,fp7
		fmove.s		fp6,po_Fx(a0)
		fmove.l		fp6,d1
		move.l		d1,po_Sx(a0)

		fmove.s		fp7,po_Fy(a0)
		fmove.l		fp7,d2
		move.l		d2,po_Sy(a0)

		moveq		#0,d0

		fcmp.s		#$41800000,fp3
		fboge		.Far

.Skip
		fmove.s		po_X(a0),fp0
		fmul.s		_ClipScaleX,fp0
		fmove.s		po_Y(a0),fp1
		fmul.s		_ClipScaleY,fp1

		fcmp		fp3,fp0
		fbole		.NoRight
		or.b		#CC_OFF_RIGHT,d0
.NoRight	fcmp		fp3,fp1
		fbole		.NoTop
		or.b		#CC_OFF_TOP,d0
.NoTop		fneg		fp3
		fcmp		fp3,fp0
		fboge		.NoLeft
		or.b		#CC_OFF_LEFT,d0
.NoLeft		fcmp		fp3,fp1
		fboge		.Done
		or.b		#CC_OFF_BOT,d0
.NoBottom	move.b		d0,po_CCodes(a0)
		rts

.Far		tst.l		d1
		bpl.s		.NoMinX
		moveq		#CC_OFF_LEFT,d0
		bra.s		.NoMaxX
.NoMinX
		cmp.l		_ClipX,d1
		ble.s		.NoMaxX
		moveq		#CC_OFF_RIGHT,d0
.NoMaxX		tst.l		d2
		bpl.s		.NoMinY
		or.b		#CC_OFF_TOP,d0
		bra.s		.Done
.NoMinY
		cmp.l		_ClipY,d2
		ble.s		.Done
		or.b		#CC_OFF_BOT,d0

.Done		move.b		d0,po_CCodes(a0)
		rts
		endc

;-------------------------------------------------------------
		XDEF		_DrawFaceSw
		cnop		0,4
_DrawFaceSw	movem.l		d2-d4/a2-a3,-(a7)

		clr.l		_PPoints

		move.l		_FreeSurfSpans,d0
		cmp.l		_LastSurfSpan,d0	;none free surfspan !
		beq		.SkipPoly

		addq.l		#1,_DrawnFaces

		move.l		_PFace,a3

		move.w		fac_NumEdges(a3),d5
		move.l		fac_FirstEdge(a3),a4

		move.l		_Matrix,a2
		lea		36(a2),a6

		move.l		#$4e800000,_PMipDist	;max...

		moveq		#0,d3
		moveq		#-1,d4

		move.l		_FreePoints,a0		;first point
		move.l		a0,_PPoints
		bra.s		.Begin

		cnop		0,4

.VertLoop	move.l		po_Next(a0),a0
.Begin		move.l		ms_MEdge(a4),a1
		add.l		ms_Type(a4),a1

		move.l		md_FirstVertex(a1),a1

		fmove.s		vc_X(a1),fp0
		fsub.s		vc_X(a6),fp0
		fmul		fp0,fp0
		fmove.s		vc_Y(a1),fp1
		fsub.s		vc_Y(a6),fp1
		fmul		fp1,fp1
		fadd		fp1,fp0
		fmove.s		vc_Z(a1),fp1
		fsub.s		vc_Z(a6),fp1
		fmul		fp1,fp1
		fadd		fp1,fp0

		fcmp.s		_PMipDist,fp0
		fbogt		.Bigger
		fmove.s		fp0,_PMipDist

.Bigger		bsr		_TransPoint

		and.b		d0,d4
		or.b		d0,d3

		addq.l		#ms_Sizeof,a4
		addq.l		#1,_DrawnEdges
		subq.b		#1,d5
		bne.s		.VertLoop

		move.l		po_Next(a0),_FreePoints
		move.l		a0,_PLastPoint
		move.l		_PPoints,po_Next(a0)	;cycle

DOFACE		equ	*
		tst.b		d4
		bne		.SkipPoly

		;fmove.s		_PMipDist,fp0
		;fsqrt		fp0
		;fcmp.l		#500,fp0
		;fboge		.SkipPoly

		move.b		d3,d0
		beq.b		.ClipDone

		bsr		_ClipPoly

.ClipDone	move.l		_PPoints,d3
		beq		.SkipPoly
		move.l		d3,a0

		move.l		po_Sy(a0),d1
		move.l		d1,d4
		move.l		d1,d5
		bra.s		.NoMaxY

		bra.s		.ScanLoop
		cnop		0,4
.ScanLoop	move.l		po_Sy(a0),d1
		cmp.l		d4,d1
		bge.s		.NoMinY
		move.l		d1,d4
		bra.s		.NoMaxY
.NoMinY		cmp.l		d5,d1
		ble.s		.NoMaxY
		move.l		d1,d5
.NoMaxY		move.l		po_Next(a0),a0
		cmp.l		d3,a0
		bne.s		.ScanLoop

		move.l		#$ffff,a4

		add.l		a4,d4
		swap		d4
		move.w		d4,_y		;Top

		add.l		a4,d5
		swap		d5
		move.w		d5,_ey		;Bottom

		sub.w		d4,d5
		ble		.SkipPoly

		move.l		#_scan,a3
		move.l		_PPoints,d0
		move.l		d0,a0
		fmove.s		#$47800000,fp3	;65536.0

.PolyLoop	move.l		a0,a2
		move.l		po_Next(a0),a1
		move.l		a1,a0

		move.l		po_Sy(a1),d2
		move.l		po_Sy(a2),d4
		cmp.l		d4,d2
		bgt.s		.Right

		moveq		#0,d7
		bra.b		.Left

.Right		exg		a1,a2
		exg		d2,d4
		move.l		#2048,d7

.Left		move.l		d2,d1
		add.l		a4,d1		;Round(Y1)
		move.l		d1,d6
		swap		d1		;Fix(Y1)

		add.l		a4,d4		;Round(Y2)
		swap		d4		;Fix(Y2)

		sub.w		d1,d4
		ble		.SkipEdge

		fmove.s		po_Fx(a2),fp0
		fsub.s		po_Fx(a1),fp0	;Dx<<16
		fmove.s		po_Fy(a2),fp1
		fsub.s		po_Fy(a1),fp1	;Dy<<16
		fdiv		fp1,fp0		;(Dx<<16)/(Dy<<16)=IncX

		clr.w		d6
		sub.l		d2,d6

		fmove		fp0,fp1
		fmul		fp3,fp1
		fmove.l		fp1,d5		;IncX<<16

		fmul.l		d6,fp0

		lea		(a3,d1.w*2),a2
		add.l		d7,a2
		swap		d5

		fadd.s		po_Fx(a1),fp0
		fmove.l		fp0,d6

		add.l		a4,d6
		swap		d6

		ext.l		d4
		add.l		d4,d4

		add.l		a2,d4
		sub.w		d5,d6
		add.l		d5,d6

		bra.s		.EdgeLoop

		cnop		0,4
.EdgeLoop	move.w		d6,(a2)+
		addx.l		d5,d6
		cmp.l		d4,a2
		bne.s		.EdgeLoop

.SkipEdge	cmp.l		d0,a0
		bne		.PolyLoop

SPtr		equr		a1

GETSPAN		MACRO
		move.l		SPtr,\1
		move.l		sp_NextSurf(SPtr),SPtr
		ENDM

		;upper half of Y is sort key
		move.w		_PBspKey,d7
		swap		d7
		moveq		#0,d6
		move.w          _y,d7
		lea		(_scan,d7.w*2),a0
		lea		(2048,a0),a6

		move.w		d7,d2
		mulu		#sp_Sizeof,d2
		lea		(_YSpans,d2.l),a2
		move.l		_FreeSpans,SPtr
		move.l		SPtr,fspan		;save first span !
		moveq		#sp_Sizeof,d3
		move.w		_ey,d4
		bra.s		.AddY
		cnop		0,4
.AddY		move.w		(a0)+,d1		;StartX
		move.w		(a6)+,d2		;EndX
		cmp.w		d1,d2
		ble.s		.SkipSpan
		move.l		a2,a4
		bra.s		.Skip
		cnop		0,4
.AddX		move.l		d0,a4
		move.w		sp_Ex(a4),d5
		cmp.w		d5,d1
		bge.s		.Skip
		move.w		sp_Sx(a4),d6
		cmp.w		d6,d1
		bge.s		.LeftClip

		GETSPAN		a3

		move.l		a3,sp_Next(a5)
		move.l		a4,sp_Next(a3)
		;move.l		d7,sp_Key(a3)		;write Y and key too
		move.w		d7,sp_Y(a3)
		move.w		d1,sp_Sx(a3)
		cmp.w		d6,d2
		ble.s		.Last
		move.w		d6,sp_Ex(a3)

.LeftClip	cmp.w		d5,d2
		ble.s		.SkipSpan
		move.w		d5,d1

.Skip		move.l		a4,a5			;prev
		move.l		sp_Next(a4),d0
		bne.s		.AddX

		GETSPAN		a3
		move.l		a3,sp_Next(a5)
		clr.l		sp_Next(a3)
		;move.l		d7,sp_Key(a3)		;write Y and key too
		move.w		d7,sp_Y(a3)
		move.w		d1,sp_Sx(a3)
.Last		move.w		d2,sp_Ex(a3)

.SkipSpan	add.l		d3,a2
		addq.w		#1,d7
		cmp.w		d4,d7
		bne		.AddY


		move.l		fspan,a6
		cmp.l		SPtr,a6		;none spans stored
		beq.s		.SkipPoly

		clr.l		sp_NextSurf(a3)
		move.l		_FreeSurfSpans,a0

		move.l		_PFace,ss_Face(a0)
		move.l		_PMipDist,ss_MipLevel(a0)
		move.l		_PThing,ss_Entity(a0)
		move.l		a6,ss_FirstSpan(a0)

		lea		ss_Sizeof(a0),a0
		move.l		a0,_FreeSurfSpans
		move.l		SPtr,_FreeSpans

.SkipPoly	move.l		_PPoints,d0
		beq.s		.NoFree

		;free alocated Points !

		move.l		_PLastPoint,a0
		move.l		_FreePoints,po_Next(a0)
		move.l		d0,_FreePoints		;free the whole chain

.NoFree		movem.l		(a7)+,d2-d4/a2-a3
		rts

fspan		ds.l		1


		XDEF		_DrawSpans
		cnop	0,4
_DrawSpans	pushm		d0-d7/a0-a6
		fmovem		fp0-fp7,-(sp)
		move.l		_FreeSurfSpans,a1

.NextSurf	cmp.l		#_SurfSpans,a1
		beq		.Last

		sub.l		#ss_Sizeof,a1

		move.l		ss_Face(a1),d0
		bne.s		.NoObject

		move.l		ss_MipLevel(a1),_TLight
		move.l		ss_Entity(a1),a0
		jsr		_RenderTObject
		bra		.SkipPoly

.NoObject	move.l		ss_FirstSpan(a1),a3

		move.l		a1,-(sp)

		move.l		d0,a2
		move.l		a2,_PFace

		move.l		fac_Flags(a2),_PPolyType

		fmove.w		fac_u0(a2),fp0
		fmove.s		fp0,_Pu
		fmove.w		fac_v0(a2),fp0
		fmove.s		fp0,_Pv

		move.l		fac_TexInfo(a2),a2
		move.l		a2,_PTexInfo

		moveq		#0,d0

		cmp.l		#1,ti_Flags(a2)
		beq.s		.Mip

		fmove.s		ss_MipLevel(a1),fp0
		fcmp.s		_MipDists+4,fp0
		fbolt		.Mip
		moveq		#1,d0
		fcmp.s		_MipDists+8,fp0
		fbolt		.Mip
		moveq		#2,d0
		fcmp.s		_MipDists+12,fp0
		fbolt		.Mip
		moveq		#3,d0

.Mip		move.l		d0,_PMipLevel

		move.l		ti_MipTex(a2),_PMipTex

		move.l		#_ViewMatrix,_Matrix
		move.l		#_ViewMatrix+36,a0

		move.l		ss_Entity(a1),_PThing
		beq.s		.SkipEnt

		move.l		_PThing,a2
		cmp.b		#TKIND_FUNC,tg_Kind(a2)
		bne.s		.SkipEnt

		move.l		tg_Extended(a2),a2
		fmove.s		vc_X(a0),fp0
		fmove.s		vc_Y(a0),fp1
		fmove.s		vc_Z(a0),fp2
		move.l		#_MViewMatrix+36,a0
		fsub.s		fc_OffsetX(a2),fp0
		fsub.s		fc_OffsetY(a2),fp1
		fsub.s		fc_OffsetZ(a2),fp2
		fmove.s		fp0,vc_X(a0)
		fmove.s		fp1,vc_Y(a0)
		fmove.s		fp2,vc_Z(a0)
		move.l		#_MViewMatrix,_Matrix

.SkipEnt	jsr		_GetTexture

		jsr		_TransformFace

		move.l		#_PMagic,a0
		move.l          _PBitMap+bmp_Bits,a2

		move.w		sp_Y(a3),d0
		move.l		(_OutputRows,d0.w*4),a1
		fmove.w		d0,fp4
		moveq		#0,d0
		fmove.s		(2*ma_Sizeof,a0),fp0
		fmul		fp4,fp0
		fadd.s		(a0)+,fp0
		fmove.s		(4*ma_Sizeof,a0),fp1
		fmul		fp4,fp1
		fadd.s		(2*ma_Sizeof,a0),fp1
		fmove.s		(7*ma_Sizeof,a0),fp2
		fmul		fp4,fp2
		fadd.s		(5*ma_Sizeof,a0),fp2

		fmove.s		(6*ma_Sizeof,a0),fp7

		move.l		a3,d1

		tst.b		_PSky
		beq.s		.NoSkyPoly
		move.w		#7,TexShift
		move.w		#$3f80,TexMaskY
		move.w		#127,TexMaskX
		bra.s		.FixedFloor

.NoSkyPoly	tst.b		_PWater
		beq.s		.NoWater

		move.w		#6,TexShift
		move.w		#$fc0,TexMaskY
		move.w		#63,TexMaskX
		tst.b		_PFloor
		beq.s		.Fixed

.FixedFloor	fmove.l		_ClampX,fp3
		fmove.s		fp3,_FClampX
		fmove.l		_ClampY,fp3
		fmove.s		fp3,_FClampY

		jsr		DrawFixedFloor
		bra.s		.PolyDone

.Fixed		jsr		DrawFixedPoly
		bra.s		.PolyDone

.NoWater	tst.b		_PFloor
		beq.s		.NoFloor

.FloorPoly	jsr		DrawFloorPoly
		bra.s		.PolyDone

.NoFloor	fmove.s		(3*ma_Sizeof,a0),fp3

		jsr		_DrawPoly

.PolyDone	move.l		(sp)+,a1

		move.l		_FreeSpans,sp_NextSurf(a3)	;free the whole chain of spans
		move.l		ss_FirstSpan(a1),_FreeSpans

.SkipPoly	bra		.NextSurf

.Last		fmovem		(sp)+,fp0-fp7
		popm		d0-d7/a0-a6
		rts
	endc
;-------------------------------------------------------------

TRANS_HIPIXEL	MACRO
		move.w		\4,\7
		addx.l		\6,\4
		move.b		\3,\7
		addx.l		\5,\3
		move.w		(\1,\7.l*2),(\2)+
		ENDM

SUBDIV_SHIFT16	equ     4
SUBDIV16	equ	1<<SUBDIV_SHIFT16

;-------------------------------------------------------------
		XDEF		_DrawPoly
		cnop		0,4

		IFEQ		P060
_DrawPoly	subq.l		#4,sp
		moveq		#0,d3
.RowLoop	move.l		d1,a3		;aligned
		move.l		sp_Sx(a3),d1
		move.w		d1,d2
		swap		d1

		fmove.w		d1,fp5
		fmove		fp7,fp4

		fmul		fp5,fp4
		fadd		fp2,fp4         ;w0

		fmove.s		#$47800000,fp6
		fdiv		fp4,fp6         ;65536.0/z

		ext.l		d1
		sub.w		d1,d2           ;width
		lea		(a1,d1.w*2),a4

		fmove.s		(a0),fp4
		fmul		fp5,fp4
		fadd		fp0,fp4
		fmul		fp6,fp4         ;u0
		fmove.l		fp4,d4		;u

		tst.l		d4
		bpl.s		.OkMinX
		moveq		#0,d4
.OkMinX		cmp.l		_ClampX,d4
		ble.s		.OkMaxX
		move.l		_ClampX,d4
.OkMaxX
		move.l		d4,a5

		fmul		fp3,fp5
		fadd		fp1,fp5
		fmul		fp6,fp5         ;v0
		fmove.l		fp5,d5          ;v

		tst.l		d5
		bpl.s		.OkMinY
		moveq		#0,d5
.OkMinY		cmp.l		_ClampY,d5
		ble.s		.OkMaxY
		move.l		_ClampY,d5
.OkMaxY
		fmove		fp7,fp4
                move.l		d5,a6

		moveq		#SUBDIV16,d3      ;len
		cmp.w		d3,d2
		bge.s		.Bigger
		move.w		d2,d3

.Bigger		add.w		d3,d1           ;e,sx+len

		fmove.w		d1,fp5

		fmul		fp5,fp4
		fadd		fp2,fp4
		fmove.s		#$47800000,fp6
		fdiv		fp4,fp6         ;65536.0/z

.SpanLoop       move.l		a5,d4          ;u
		move.l		a6,d5          ;v

		fmove.s		(a0),fp4
		fmul		fp5,fp4
		fadd		fp0,fp4
		fmul		fp6,fp4         ;u1
		fmove.l		fp4,d6

		fmul		fp3,fp5
		fadd		fp1,fp5
		fmul		fp6,fp5         ;u1
		fmove.l		fp5,d7


		sub.w		d3,d2                   ;width-=len
		bgt.s		.SkipClamp

		tst.l		d6
		bpl.s		.OkMinX2
		moveq		#0,d6
.OkMinX2	cmp.l		_ClampX,d6
		ble.s		.OkMaxX2
		move.l		_ClampX,d6
.OkMaxX2	tst.l		d7
		bpl.s		.OkMinY2
		moveq		#0,d7
.OkMinY2	cmp.l		_ClampY,d7
		ble.s		.OkMaxY2
		move.l		_ClampY,d7
.OkMaxY2

.SkipClamp	move.l		d6,a5
		sub.l		d4,d6
		move.w		d4,d0
		move.w		d5,d4
		swap		d4


		move.l		d7,a6
		sub.l		d5,d7
		rol.l		#8,d5

		move.w		d0,d5
		swap		d5

		tst.w		d2
		beq		.Div

		asr.l		#SUBDIV_SHIFT16,d6
		rol.l		#8-SUBDIV_SHIFT16,d7

		exgw		d6,d7

		swap		d6
		swap		d7

		fmove		fp7,fp4
		moveq		#SUBDIV16,d3      ;len
		cmp.w		d3,d2
		bge.s		.Bigger2
		move.w		d2,d3
.Bigger2	add.w		d3,d1           ;e,sx+len
		fmove.w		d1,fp5
		move.w		d2,(sp)

		fmul		fp5,fp4

		sub.w		d6,d4
		add.l		d6,d4

		move.w		d5,d0
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		fadd		fp2,fp4
		move.w		d5,d0
		swap		d2
		fmove.s		#$47800000,fp6
		addx.l		d7,d5
		move.b		d4,d0
		fdiv		fp4,fp6         ;65536.0/z
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+

		REPT		2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+
		ENDR

		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		move.w		(a2,d0.l*2),d2
		move.l		d2,(a4)+

		move.w		(sp),d2
		bgt		.SpanLoop
		bra.s		.Skip

		cnop		0,4
.Div		move.w		(Divisors,d3.w*2),d0
		muls.l		d0,d6
		muls.l		d0,d7
		asr.l		#8,d6

		exgw		d6,d7

		swap		d6
		swap		d7

		add.l		d3,d3
		add.l		a4,d3

		sub.w		d6,d4
		add.l		d6,d4
		cnop		0,4

.AffineLoop	move.w		d5,d0
		addx.l		d7,d5
		move.b		d4,d0
		addx.l		d6,d4
		move.w		(a2,d0.l*2),(a4)+
		cmp.l		d3,a4
		bne.s		.AffineLoop

.Skip		move.l		sp_NextSurf(a3),d1
		beq.s		.Out
		move.l		d1,a4
		move.w		sp_Y(a4),d4
		sub.w		sp_Y(a3),d4
		beq		.RowLoop
		cmp.w		#1,d4
		beq.s		.Simple
		fmove.w		d4,fp4
		mulu		_OutputWidth+2,d4
		add.l		d4,a1
		fmove.s		(1*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp0
		fmove.s		(4*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp1
		fmul.s		(7*ma_Sizeof,a0),fp4
		fadd		fp4,fp2
		bra		.RowLoop

.Simple		fadd.s		(1*ma_Sizeof,a0),fp0
		fadd.s		(4*ma_Sizeof,a0),fp1
		fadd.s		(7*ma_Sizeof,a0),fp2
		add.l		_OutputWidth,a1
		bra		.RowLoop

.Out		addq.l		#4,sp
		rts

		cnop		0,4
Divisors	dc.w		0,256,128,85,64,51,42,36,32,28,25,23,21,19,18,17,16


		ELSE

;-------------------------------------------------------------
_DrawPoly	subq.l		#4,sp
		moveq		#0,d3
.RowLoop	move.l		d1,a3		;aligned
		move.l		sp_Sx(a3),d1
		move.w		d1,d2
		swap		d1

		fmove.w		d1,fp5
		fmove		fp7,fp4

		fmul		fp5,fp4
		fadd		fp2,fp4         ;w0

		fmove.s		#$47800000,fp6
		fdiv		fp4,fp6         ;65536.0/z

		ext.l		d1
		sub.w		d1,d2           ;width
		lea		(a1,d1.w*2),a4

		fmove.s		(a0),fp4
		fmul		fp5,fp4
		fadd		fp0,fp4
		fmul		fp6,fp4         ;u0
		fmove.l		fp4,d4		;u

		tst.l		d4
		bpl.s		.OkMinX
		moveq		#0,d4
.OkMinX		cmp.l		_ClampX,d4
		ble.s		.OkMaxX
		move.l		_ClampX,d4
.OkMaxX
		move.l		d4,a5

		fmul		fp3,fp5
		fadd		fp1,fp5
		fmul		fp6,fp5         ;v0
		fmove.l		fp5,d5          ;v

		tst.l		d5
		bpl.s		.OkMinY
		moveq		#0,d5
.OkMinY		cmp.l		_ClampY,d5
		ble.s		.OkMaxY
		move.l		_ClampY,d5
.OkMaxY
		fmove		fp7,fp4
                move.l		d5,a6

		moveq		#SUBDIV16,d3      ;len
		cmp.w		d3,d2
		bge.s		.Bigger
		move.w		d2,d3

.Bigger		add.w		d3,d1           ;e,sx+len

		fmove.w		d1,fp5

		fmul		fp5,fp4
		fadd		fp2,fp4
		fmove.s		#$47800000,fp6
		fdiv		fp4,fp6         ;65536.0/z

.SpanLoop       move.l		a5,d4          ;u
		move.l		a6,d5          ;v

		fmove.s		(a0),fp4
		fmul		fp5,fp4
		fadd		fp0,fp4
		fmul		fp6,fp4         ;u1
		fmove.l		fp4,d6

		fmul		fp3,fp5
		fadd		fp1,fp5
		fmul		fp6,fp5         ;u1
		fmove.l		fp5,d7


		sub.w		d3,d2                   ;width-=len
		bgt.s		.SkipClamp

		tst.l		d6
		bpl.s		.OkMinX2
		moveq		#0,d6
.OkMinX2	cmp.l		_ClampX,d6
		ble.s		.OkMaxX2
		move.l		_ClampX,d6
.OkMaxX2	tst.l		d7
		bpl.s		.OkMinY2
		moveq		#0,d7
.OkMinY2	cmp.l		_ClampY,d7
		ble.s		.OkMaxY2
		move.l		_ClampY,d7
.OkMaxY2

.SkipClamp	move.l		d6,a5
		sub.l		d4,d6
		move.w		d4,d0
		move.w		d5,d4
		swap		d4


		move.l		d7,a6
		sub.l		d5,d7
		rol.l		#8,d5

		move.w		d0,d5
		swap		d5

		tst.w		d2
		beq		.Div

		asr.l		#SUBDIV_SHIFT16,d6
		rol.l		#8-SUBDIV_SHIFT16,d7

		exgw		d6,d7

		swap		d6
		swap		d7

		fmove		fp7,fp4
		moveq		#SUBDIV16,d3      ;len
		cmp.w		d3,d2
		bge.s		.Bigger2
		move.w		d2,d3
.Bigger2	add.w		d3,d1           ;e,sx+len
		fmove.w		d1,fp5
		move.w		d2,(sp)

		fmul		fp5,fp4

		sub.w		d6,d4
		add.l		d6,d4

		move.w		d5,d0
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		fadd		fp2,fp4
		move.w		d5,d0
		swap		d2
		fmove.s		#$47800000,fp6
		addx.l		d7,d5
		move.b		d4,d0
		fdiv		fp4,fp6         ;65536.0/z
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+

		REPT		2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+
		ENDR

		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		move.l		d2,(a4)+
		move.b		d4,d0
		addx.l		d7,d5
		move.w		(a2,d0.l*2),d2
		addx.l		d6,d4
		move.w		d5,d0
		swap		d2
		move.b		d4,d0
		move.w		(a2,d0.l*2),d2
		move.l		d2,(a4)+

		move.w		(sp),d2
		bgt		.SpanLoop
		bra.s		.Skip

		cnop		0,4
.Div		fmove.s		(_FDivisors,d3.w*4),fp4
		fmove.l		d6,fp5
		fmul		fp4,fp5
		fmove.l		fp5,d6
		fmul.l		d7,fp4
		fmove.l		fp4,d7

		asr.l		#8,d6

		exgw		d6,d7

		swap		d6
		swap		d7

		add.l		d3,d3
		add.l		a4,d3

		sub.w		d6,d4
		add.l		d6,d4
		cnop		0,4

.AffineLoop	move.w		d5,d0
		addx.l		d7,d5
		move.b		d4,d0
		addx.l		d6,d4
		move.w		(a2,d0.l*2),(a4)+
		cmp.l		d3,a4
		bne.s		.AffineLoop

.Skip		move.l		sp_NextSurf(a3),d1
		beq.s		.Out
		move.l		d1,a4
		move.w		sp_Y(a4),d4
		sub.w		sp_Y(a3),d4
		beq		.RowLoop
		cmp.w		#1,d4
		beq.s		.Simple
		fmove.w		d4,fp4
		mulu		_OutputWidth+2,d4
		add.l		d4,a1
		fmove.s		(1*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp0
		fmove.s		(4*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp1
		fmul.s		(7*ma_Sizeof,a0),fp4
		fadd		fp4,fp2
		bra		.RowLoop

.Simple		fadd.s		(1*ma_Sizeof,a0),fp0
		fadd.s		(4*ma_Sizeof,a0),fp1
		fadd.s		(7*ma_Sizeof,a0),fp2
		add.l		_OutputWidth,a1
		bra		.RowLoop

.Out		addq.l		#4,sp
		rts
		ENDC

;-------------------------------------------------------------
		cnop		0,4
DrawFloorPoly
.RowLoop	move.l		d1,a3
		move.l		sp_Sx(a3),d1
		move.w		d1,d2
		swap		d1

		fmove.s		#$47800000,fp6
		fdiv		fp2,fp6         ;z

		ext.l		d2
		ext.l		d1
		move.l		d2,d3
		sub.w		d1,d3           ;width

		fmove.w		d1,fp3

		fmove.s         (a0),fp4
		fmove		fp4,fp7
		fmul		fp3,fp4
		fadd		fp0,fp4
		fmul		fp6,fp4         ;u0
		fboge		.OkMinX0
		fmove.s		#0,fp4
.OkMinX0	fcmp.l		_ClampX,fp4
		fbole		.OkMaxX0
		fmove.l		_ClampX,fp4
.OkMaxX0
		fmove.s         (3*ma_Sizeof,a0),fp5
		fmul            fp3,fp5
		fadd            fp1,fp5
		fmove.w		d2,fp3
		fmul            fp6,fp5         ;v0
		fboge		.OkMinY0
		fmove.s		#0,fp5
.OkMinY0	fcmp.l		_ClampY,fp5
		fbole		.OkMaxY0
		fmove.l		_ClampY,fp5

.OkMaxY0
		fmul		fp3,fp7
		fadd		fp0,fp7
		fmul		fp6,fp7         ;u1
		fboge		.OkMinX1
		fmove.s		#0,fp7
.OkMinX1	fcmp.l		_ClampX,fp7
		fbole		.OkMaxX1
		fmove.l		_ClampX,fp7
.OkMaxX1
		fmul.s		(3*ma_Sizeof,a0),fp3
		fadd		fp1,fp3
		fmul		fp6,fp3         ;v1
		fboge		.OkMinY1
		fmove.s		#0,fp3
.OkMinY1	fcmp.l		_ClampY,fp3
		fbole		.OkMaxY1
		fmove.l		_ClampY,fp3

.OkMaxY1	fmove.l		fp4,d4          ;u
		fmove.l		fp5,d5          ;v

		fsub		fp4,fp7
		fsub		fp5,fp3
		fmove.s		#$3f800000,fp4
		fdiv.w		d3,fp4


		lea		(a1,d1.l*2),a4	;dest

		fmul		fp4,fp7

		rol.l		#8,d5

		fmove.l		fp7,d6
		fmul		fp4,fp3

		move.w		d4,d0
		move.w		d5,d4
		move.w		d0,d5
		swap		d4
		swap		d5

		fmove.l		fp3,d7
		rol.l		#8,d7

		exgw		d6,d7

		swap		d6
		swap		d7

		ext.l		d3
		move.l		d3,d1
		and.w		#$000f,d3
		and.w		#$fff0,d1
		beq		.Remain

		add.l		d1,d1
		add.l		a4,d1

		sub.w		d6,d4
		add.l		d6,d4

.BigLoop	move.w		d5,d0
		move.b		d4,d0
		REPT		3
		addx.l		d7,d5
		addx.l		d6,d4
		move.w		(a2,d0.l*2),d2
		move.w		d5,d0
		move.b		d4,d0
		swap		d2
		addx.l		d7,d5
		addx.l		d6,d4
		move.w		(a2,d0.l*2),d2
		move.w		d5,d0
		move.l		d2,(a4)+
		move.b		d4,d0
		addx.l		d7,d5
		addx.l		d6,d4
		move.w		(a2,d0.l*2),d2
		move.w		d5,d0
		move.b		d4,d0
		swap		d2
		addx.l		d7,d5
		addx.l		d6,d4
		move.w		(a2,d0.l*2),d2
		move.w		d5,d0
		move.b		d4,d0
		move.l		d2,(a4)+
		ENDR

		addx.l		d7,d5
		addx.l		d6,d4
		move.w		(a2,d0.l*2),d2
		move.w		d5,d0
		move.b		d4,d0
		swap		d2
		addx.l		d7,d5
		addx.l		d6,d4
		move.w		(a2,d0.l*2),d2
		move.w		d5,d0
		move.l		d2,(a4)+
		move.b		d4,d0
		addx.l		d7,d5
		addx.l		d6,d4
		move.w		(a2,d0.l*2),d2
		move.w		d5,d0
		move.b		d4,d0
		swap		d2
		addx.l		d7,d5
		addx.l		d6,d4
		move.w		(a2,d0.l*2),d2
		move.l		d2,(a4)+

		cmp.l		d1,a4
		bne		.BigLoop
		bra.s		.Last


.Remain
.Last		add.l		d3,d3
		beq.s		.Skip

		add.l		a4,d3

		sub.w		d6,d4
		add.l		d6,d4

.AffineLoop	move.w		d5,d0
		move.b		d4,d0
		addx.l		d7,d5
		addx.l		d6,d4
		move.w		(a2,d0.l*2),(a4)+
		cmp.l		d3,a4
		bne.s		.AffineLoop


.Skip		move.l		sp_NextSurf(a3),d1
		beq.s		.Out
		move.l		d1,a4
		move.w		sp_Y(a4),d4
		sub.w		sp_Y(a3),d4
		beq		.RowLoop

		cmp.w		#1,d4
		beq.s		.Simple
		fmove.w		d4,fp4
		mulu		_OutputWidth+2,d4
		add.l		d4,a1
		fmove.s		(1*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp0
		fmove.s		(4*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp1
		fmove.s		(7*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp2
		bra		.RowLoop

.Simple		fadd.s		(1*ma_Sizeof,a0),fp0
		fadd.s		(4*ma_Sizeof,a0),fp1
		fadd.s		(7*ma_Sizeof,a0),fp2

		add.l		_OutputWidth,a1
		bra		.RowLoop

.Out		rts

;-------------------------------------------------------------
		cnop		0,4
DrawFixedFloor

.RowLoop	move.l		d1,a3
		move.l		sp_Sx(a3),d1

		move.w		d1,d2
		swap		d1

		fmove.s		#$47800000,fp6
		fdiv		fp2,fp6         ;z

		ext.l		d2
		ext.l		d1

		move.w		d2,d3
		sub.w		d1,d3           ;width

		fmove.s         (a0),fp4
		fmove		fp4,fp7
		fmul.w          d1,fp4
		fadd            fp0,fp4
		fmul            fp6,fp4         ;u0

		fmul.w		d2,fp7
		fadd		fp0,fp7
		fmul		fp6,fp7         ;u1

		fmove.s         (3*ma_Sizeof,a0),fp5
		fmove		fp5,fp3
		fmul.w          d1,fp5
		fadd            fp1,fp5
		fmul            fp6,fp5         ;v0

		fmul.w		d2,fp3
		fadd		fp1,fp3
		fmul		fp6,fp3         ;v1

		fmove.l		fp4,d4          ;u

		fmove.l		fp5,d5          ;v

		lea		(a1,d1.w*2),a4

		fsub		fp4,fp7
		fsub		fp5,fp3
		fdiv.w		d3,fp7
		fdiv.w		d3,fp3

		fmove.l		fp3,d7
		fmove.l		fp7,d6

		move.w		TexShift,d0
		rol.l		d0,d5
		rol.l		d0,d7

		eor.w		d4,d5
		eor.w		d5,d4
		eor.w		d4,d5
		swap		d4
		swap		d5

		exgw		d6,d7

		swap		d6
		swap		d7

		ext.l		d3
		add.l		d3,d3
		add.l		a4,d3

		move.w		TexMaskY,d2
		move.b		TexMaskX+1,d1

		sub.w		d7,d5
		add.l		d7,d5

.AffineLoop	move.w		d5,d0
		and.w		d2,d0
		or.b		d4,d0
		move.w		(a2,d0.w*2),(a4)+
		addx.l		d6,d4
		and.b		d1,d4
		addx.l		d7,d5
		cmp.l		d3,a4
		bne.s		.AffineLoop

.Skip		move.l		sp_NextSurf(a3),d1
		beq.s		.Out
		move.l		d1,a4
		move.w		sp_Y(a4),d4
		sub.w		sp_Y(a3),d4
		beq		.RowLoop

		cmp.w		#1,d4
		beq.s		.Simple
		fmove.w		d4,fp4
		mulu		_OutputWidth+2,d4
		add.l		d4,a1
		fmove.s		(1*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp0
		fmove.s		(4*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp1
		fmove.s		(7*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp2
		bra		.RowLoop

.Simple		fadd.s		(1*ma_Sizeof,a0),fp0
		fadd.s		(4*ma_Sizeof,a0),fp1
		fadd.s		(7*ma_Sizeof,a0),fp2

		add.l		_OutputWidth,a1
		bra		.RowLoop

.Out		rts

;-------------------------------------------------------------
		cnop		0,4
DrawFixedPoly
.RowLoop	move.l		d1,a3
		move.l		sp_Sx(a3),d1
		move.w		d1,d2
		swap		d1

		fmove		fp7,fp4
		ext.l		d1
		ext.l		d2

		fmove.w		d1,fp5

		fmul		fp5,fp4
		fadd            fp2,fp4         ;w0

		fmove		fp3,fp6
		fdiv            fp4,fp6         ;65536.0/z

		sub.w           d1,d2           ;width
		move.l		a1,a4
		add.l		d1,a4           ;dest

		fmove.s         (a0),fp4
		fmul		fp5,fp4
		fadd            fp0,fp4
		fmul            fp6,fp4         ;u0
		fmove.l         fp4,d4		;u
		move.l		d4,a5

                fmul.s		(3*ma_Sizeof,a0),fp5
		fadd            fp1,fp5
		fmul            fp6,fp5         ;v0
                fmove.l         fp5,d5          ;v
                move.l		d5,a6

.SpanLoop       fmove		fp7,fp4

		moveq           #SUBDIV16,d3      ;len
		cmp.w		d3,d2
		bge.s		.Bigger
		move.w          d2,d3

.Bigger		move.l		a5,d4          ;u
		move.l		a6,d5          ;v

		add.w           d3,d1           ;e,sx+len

		fmove.w		d1,fp5

		fmul		fp5,fp4
		fadd		fp2,fp4
		fmove		fp3,fp6
		fdiv		fp4,fp6         ;65536.0/z

		fmove.s		(a0),fp4
		fmul		fp5,fp4
		fadd		fp0,fp4
		fmul		fp6,fp4         ;u1

		fmul.s		(3*ma_Sizeof,a0),fp5
		fadd		fp1,fp5
		fmul		fp6,fp5         ;u1

		move.w		d1,-(sp)

		move.w		TexShift,d1

		fmove.l		fp4,d6
		move.l		d6,a5
		sub.l		d4,d6

		fmove.l		fp5,d7
		move.l		d7,a6
		sub.l           d5,d7

		sub.w           d3,d2                   ;width-=len

		move.w		d2,-(sp)

		cmp.w           #SUBDIV16,d3
		bne.s		.Div

		asr.l           #SUBDIV_SHIFT16,d6
		asr.l           #SUBDIV_SHIFT16,d7
		bra.s		.Shift

.Div
		IFNE		P060
		fmove.s		#$3f800000,fp4
		fdiv.l		d3,fp4
		fmove.l		d6,fp5
		fmul		fp4,fp5
		fmove.l		fp5,d6
		fmul.l		d7,fp4
		fmove.l		fp4,d7
		ELSE

		divs.l		d3,d6                   ;d6-du
		divs.l		d3,d7                   ;d7-dv
	                                                ;d4-u
                                                        ;d5-v
		ENDC

.Shift
		rol.l		d1,d5
		rol.l		d1,d7

		exgw		d4,d5

		swap		d4
		swap		d5

		exgw		d6,d7

		swap		d6
		swap		d7

		add.l		a4,d3

		move.w		TexMaskY,d2
		move.b		TexMaskX+1,d1

		sub.w		d7,d5
		add.l		d7,d5

.AffineLoop	move.w		d5,d0
		and.w		d2,d0
		or.b		d4,d0
		move.b		(a2,d0.w),(a4)+
		addx.l		d6,d4
		and.b		d1,d4
		addx.l		d7,d5
		cmp.l		d3,a4
		bne.s		.AffineLoop

		move.w		(sp)+,d2
		move.w		(sp)+,d1

		tst.w		d2
		bgt		.SpanLoop

.Skip		move.l		sp_NextSurf(a3),d1
		beq.s		.Out
		move.l		d1,a4
		move.w		sp_Y(a4),d4
		sub.w		sp_Y(a3),d4
		beq		.RowLoop

		cmp.w		#1,d4
		beq.s		.Simple
		fmove.w		d4,fp4
		mulu		_OutputWidth+2,d4
		add.l		d4,a1
		fmove.s		(1*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp0
		fmove.s		(4*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp1
		fmove.s		(7*ma_Sizeof,a0),fp5
		fmul		fp4,fp5
		fadd		fp5,fp2
		bra		.RowLoop

.Simple		fadd.s		(1*ma_Sizeof,a0),fp0
		fadd.s		(4*ma_Sizeof,a0),fp1
		fadd.s		(7*ma_Sizeof,a0),fp2

		add.l		_OutputWidth,a1
		bra		.RowLoop

.Out		rts

;---------------------------------------------------------------------
;			3D_Clip
;---------------------------------------------------------------------
		XDEF		_ClipPoly

		cnop		0,4
_ClipPoly	movem.l		d2-d7/a2-a6,-(a7)
		move.b		d0,d7

		fmove.s		_ClipScaleX,fp6
		fmove.s		_ClipScaleY,fp7

		move.l		_FreePoints,a4		;chain of free points
		move.l		#TmpPoints,a5		;temporary chain of freed points
		clr.l		(a5)

		btst		#CC_BIT_LEFT,d7
		beq		NoLeftClip

		moveq		#CC_OFF_LEFT,d5

		move.l		#_PPoints,a6
		move.l		(a6),a2
		move.l		a2,d4
		clr.l		(a6)

LeftClipLoop	move.b		po_CCodes(a2),d0

;Every point is either added to the PPoints chain or freed to the temporary chain

		btst		#CC_BIT_LEFT,d0
		bne.s		.Free

		move.l		a2,po_Next(a6)
		move.l		a2,a6
		bra.s		.Clip

.Free		move.l		a2,po_Next(a5)
		move.l		a2,a5

.Clip		move.l		po_Next(a2),a1
		move.b		po_CCodes(a1),d1
		eor.b		d1,d0
		and.b		d5,d0
		beq.b		.NoClip

		fmove.s		po_Z(a1),fp2
		fmove		fp2,fp0
		fmove.s		po_X(a1),fp1
		fmul		fp6,fp1
		fadd		fp1,fp0
		fneg		fp0

		fmove.s		po_X(a2),fp1
		fsub.s		po_X(a1),fp1
		fmul		fp6,fp1
		fadd.s		po_Z(a2),fp1
		fsub		fp2,fp1

		bsr		Intersect

.NoClip		move.l		a1,a2
		cmp.l		d4,a1
		bne		LeftClipLoop

		tst.l		_PPoints
		beq		SkipAll

		move.l		_PPoints,po_Next(a6)	;Enclose cycle

NoLeftClip	btst		#CC_BIT_RIGHT,d7
		beq		NoRightClip

		moveq		#CC_OFF_RIGHT,d5

		move.l		#_PPoints,a6
		move.l		(a6),a2
		move.l		a2,d4
		clr.l		(a6)

RightClipLoop	move.b		po_CCodes(a2),d0
		move.l		po_Next(a2),a1
		btst		#CC_BIT_RIGHT,d0
		bne.s		.Free

;Every point is either added to PPoints chain or freed

		move.l		a2,po_Next(a6)
		move.l		a2,a6
		bra.s		.Clip

.Free		move.l		a2,po_Next(a5)
		move.l		a2,a5

.Clip		move.b		po_CCodes(a1),d1
		eor.b		d1,d0
		and.b		d5,d0
		beq.b		.NoClip

		fmove.s		po_Z(a1),fp0
		fmove		fp0,fp4
		fmove.s		po_X(a1),fp1
		fmove		fp1,fp2
		fmul		fp6,fp1
		fsub		fp1,fp0

		fmove.s		po_X(a2),fp1
		fsub		fp2,fp1
		fmul		fp6,fp1
		fsub.s		po_Z(a2),fp1
		fadd		fp4,fp1

		bsr		Intersect

.NoClip		move.l		a1,a2
		cmp.l		d4,a1
		bne.s		RightClipLoop

		tst.l		_PPoints
		beq		SkipAll

		move.l		_PPoints,po_Next(a6)	;Enclose cycle

NoRightClip	btst		#CC_BIT_TOP,d7
		beq		NoTopClip

		moveq		#CC_OFF_TOP,d5

		move.l		#_PPoints,a6
		move.l		(a6),a2
		move.l		a2,d4
		clr.l		(a6)

TopClipLoop	move.b		po_CCodes(a2),d0
		move.l		po_Next(a2),a1
		btst		#CC_BIT_TOP,d0
		bne.s		.Free

;Every point is either added to PClipPoints chain or freed

		move.l		a2,po_Next(a6)
		move.l		a2,a6
		bra.s		.Clip

.Free		move.l		a2,po_Next(a5)
		move.l		a2,a5

.Clip		move.b		po_CCodes(a1),d1
		eor.b		d1,d0
		and.b		d5,d0
		beq.b		.NoClip

		fmove.s		po_Z(a1),fp0
		fmove		fp0,fp4
		fmove.s		po_Y(a1),fp1
		fmove		fp1,fp2
		fmul		fp7,fp1
		fsub		fp1,fp0

		fmove.s		po_Y(a2),fp1
		fsub		fp2,fp1
		fmul		fp7,fp1
		fmove.s		po_Z(a2),fp2
		fsub		fp2,fp1
		fadd		fp4,fp1

		bsr		Intersect

.NoClip		move.l		a1,a2
		cmp.l		d4,a1
		bne.s		TopClipLoop

		tst.l		_PPoints
		beq		SkipAll

		move.l		_PPoints,po_Next(a6)	;Enclose cycle

NoTopClip	btst		#CC_BIT_BOT,d7
		beq		NoBottomClip

		moveq		#CC_OFF_BOT,d5

		move.l		#_PPoints,a6
		move.l		(a6),a2
		move.l		a2,d4
		clr.l		(a6)

BottomClipLoop	move.b		po_CCodes(a2),d0
		move.l		po_Next(a2),a1
		btst		#CC_BIT_BOT,d0
		bne.s		.Free

;Every point is either added to PPoints chain or freed

		move.l		a2,po_Next(a6)
		move.l		a2,a6
		bra.s		.Clip

.Free		move.l		a2,po_Next(a5)
		move.l		a2,a5

.Clip		move.b		po_CCodes(a1),d1
		eor.b		d1,d0
		and.b		d5,d0
		beq.b		.NoClip

		fmove.s		po_Z(a1),fp0
		fmove		fp0,fp4
		fmove.s		po_Y(a1),fp1
		fmove		fp1,fp2
		fmul		fp7,fp1
		fadd		fp1,fp0
		fneg		fp0
		fmove.s		po_Y(a2),fp1
		fsub		fp2,fp1
		fmul		fp7,fp1
		fadd.s		po_Z(a2),fp1
		fsub		fp4,fp1

		bsr		Intersect

.NoClip		move.l		a1,a2
		cmp.l		d4,a1
		bne.s		BottomClipLoop

		tst.l		_PPoints
		beq		SkipAll

		move.l		_PPoints,po_Next(a6)	;Enclose cycle

NoBottomClip	move.l		a6,_PLastPoint
		moveq		#-1,d0
		bra.s		EndClip

SkipAll		moveq		#0,d0

EndClip
;free tmp chain
		move.l		TmpPoints,d0
		beq.s		.nofree

		move.l		a4,po_Next(a5)
		move.l		d0,a4

.nofree		move.l		a4,_FreePoints

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

TmpPoints	ds.l		1

;-------------------------------------------------------------
		cnop		0,4
Intersect	fdiv		fp1,fp0

		move.l		a4,a0
		move.l		po_Next(a4),a4

		fmove.s		po_X(a2),fp4
		fmove.s		po_X(a1),fp2
		fsub		fp2,fp4
		fmul		fp0,fp4
		fadd		fp2,fp4
		fmove.s		fp4,po_X(a0)
		fmove.s		po_Y(a2),fp1
		fmove.s		po_Y(a1),fp2
		fsub		fp2,fp1
		fmul		fp0,fp1
		fadd		fp2,fp1
		fmove.s		fp1,po_Y(a0)
		fmove.s		po_Z(a2),fp3
		fmove.s		po_Z(a1),fp2
		fsub		fp2,fp3
		fmul		fp0,fp3
		fadd		fp2,fp3
		fmove.s		fp3,po_Z(a0)

		fcmp.s		#$3c23d70a,fp3
		fbolt		.Skip

		fmove		fp4,fp0
		fmove		fp1,fp5

		fmove.s		#$47800000,fp2
		fdiv		fp3,fp2
		fmul		fp2,fp4

		fadd.s		_xcenter2,fp4
		fmul		fp2,fp5
		fneg		fp5
		fadd.s		_ycenter2,fp5

		fmove.s		fp4,po_Fx(a0)
		fmove.l		fp4,d1
		move.l		d1,po_Sx(a0)

		fmove.s		fp5,po_Fy(a0)
		fmove.l		fp5,d2
		move.l		d2,po_Sy(a0)

.Skip		moveq		#0,d0

		fcmp.s		#$41800000,fp3
		fboge		.Far

		ftst		fp3
		fbogt		.NoBehind

		moveq		#CC_BEHIND,d0

.NoBehind	fmul		fp6,fp4
		fcmp		fp3,fp4
		fbole		.NoRight
		or.b		#CC_OFF_RIGHT,d0
.NoRight	fmul		fp7,fp1
		fcmp		fp3,fp1
		fbole		.NoTop
		or.b		#CC_OFF_TOP,d0
.NoTop		fneg		fp3
		fcmp		fp3,fp1
		fboge		.NoBottom
		or.b		#CC_OFF_BOT,d0
.NoBottom	fcmp		fp3,fp4
		fboge		.NoLeft
		or.b		#CC_OFF_LEFT,d0
.NoLeft		bra.s		.Done

.Far		tst.l		d1
		bpl.s		.NoMinX
		moveq		#CC_OFF_LEFT,d0
		bra.s		.NoMaxX
.NoMinX
		cmp.l		_ClipX,d1
		ble.s		.NoMaxX
		moveq		#CC_OFF_RIGHT,d0
.NoMaxX		tst.l		d2
		bpl.s		.NoMinY
		or.b		#CC_OFF_TOP,d0
		bra.s		.Done
.NoMinY
		cmp.l		_ClipY,d2
		ble.s		.Done
		or.b		#CC_OFF_BOT,d0

.Done		move.b		d0,po_CCodes(a0)

		move.l		a0,po_Next(a6)
		move.l		a0,a6
		rts



;--------------------------------------------------------------
		XDEF		_QuickSort
		cnop		0,4
_QuickSort	lea		-4(a0,d0.l*4),a1
		move.l		a1,-(a7)
		move.l		a0,-(a7)
		bsr.s		.PartQuickSort
		addq.l		#8,a7
		rts

.PartQuickSort	movea.l		4(a7),a0
		movea.l		8(a7),a1
		lea		-4(a1),a2
		cmpa.l		a0,a2
		ble.s		.BubbleSort
		move.l		a1,d0
		sub.l		a0,d0
		lsr.l		#3,d0
		move.l		0(a0,d0.l*4),d0
		addq.l		#4,a1
.GetHighLoop	cmp.l		(a0)+,d0
		blt.s		.GetHighLoop
.GetLowLoop	cmp.l		-(a1),d0
		bgt.s		.GetLowLoop
		cmpa.l		a0,a1
		blt.s		.SortFinished
		move.l		-4(a0),d1
		move.l		(a1),-4(a0)
		move.l		d1,(a1)
		bra.s		.GetHighLoop

.SortFinished	subq.l		#4,a0
		move.l		8(a7),-(a7)
		move.l		a0,-(a7)
		move.l		a1,-(a7)
		move.l		$10(a7),-(a7)
		bsr.s		.PartQuickSort
		addq.l		#8,a7
		bsr.s		.PartQuickSort
		addq.l		#8,a7
		rts

.BubbleSort	move.l		(a0),d0
		cmp.l		(a1),d0
		bge.s		.NoBubbleSort
		move.l		(a1),(a0)
		move.l		d0,(a1)
.NoBubbleSort	rts



;---------------------------------------------------------------------
;			3DMath_Code
;---------------------------------------------------------------------
;		XDEF		_ChangeView
		cnop		0,4
;_ChangeView	;a0-Camera
		movem.l		d0-d2/a1-a3,-(a7)
		fmovem		fp0-fp7,-(sp)

		move.l		a0,a3

		move.l		#_ViewMatrix,a0
		move.l		#_MainMatrix,a1
		move.l		#_FloatSinCos,a2

		move.l		cam_AngleX(a3),d0		;ROLL
		move.l		d0,_ViewAngles+4
		lsr.w		#3,d0
		and.w		#1023<<3,d0
		fmove.d		(_FloatSinCos,d0.w),fp2
		fmove.d		(_FloatSinCos+2048,d0.w),fp3

		move.l		cam_AngleY(a3),d0		;YAW
		move.l		d0,_ViewAngles
		lsr.w		#3,d0
		and.w		#1023<<3,d0
		fmove.d		(_FloatSinCos,d0.w),fp4
		fmove.d		(_FloatSinCos+2048,d0.w),fp5

		move.l		#65536,d0
		sub.l		cam_AngleZ(a3),d0
		move.l		d0,_ViewAngles+8
		lsr.w		#3,d0
		sub.w		#256<<3,d0
		and.w		#1023<<3,d0
		fmove.d		(_FloatSinCos,d0.w),fp6
		fmove.d		(_FloatSinCos+2048,d0.w),fp7	;PITCH

		fmove.s		fp2,_msr
		fmove.s		fp3,_mcr
		fmove.s		fp6,_msy
		fmove.s		fp7,_mcy
		fmove.s		fp4,_msp
		fmove.s		fp5,_mcp

		move.l		cam_AngleZ(a3),d0
		move.l		d0,_ViewAngles+8
		lsr.w		#3,d0
		and.w		#1023<<3,d0
		fmove.d		(_FloatSinCos,d0.w),fp6
		fmove.d		(_FloatSinCos+2048,d0.w),fp7	;PITCH

;forward
		fmove		fp5,fp0			;cy
		fmul		fp7,fp0			;cp
		fmove.s		fp0,(a1)		;=cp*cy
		fmul.s		_ProjScaleX,fp0
		fmove.s		fp0,(a0)
		fmove		fp6,fp0			;sp
		fneg		fp0
		fmove.s		fp0,4(a1)		;=-sp
		fmul.s		_ProjScaleX,fp0
		fmove.s		fp0,4(a0)
		fmove		fp4,fp0
		fneg		fp0
		fmul		fp7,fp0
		fmove.s		fp0,8(a1)		;=cp*-1*sy
		fmul.s		_ProjScaleX,fp0
		fmove.s		fp0,8(a0)

;up
		fmove		fp5,fp0
		fmul		fp6,fp0			;sp*cy
		fmul		fp3,fp0			;cr*sp*cy
		fmove		fp4,fp1
		fneg		fp1
		fmul		fp2,fp1			;sr*-sy
		fadd		fp1,fp0
		fmove.s		fp0,12(a1)		;=(sr*-sy)+(cr*sp*cy)
		fmove.s		fp0,12(a0)
		fmove		fp7,fp0
		fmul		fp3,fp0
		fmove.s		fp0,16(a1)		;=cp*cr
		fmove.s		fp0,16(a0)
		fmove		fp4,fp0
		fneg		fp0
		fmul		fp6,fp0			;sp*-sy
		fmul		fp3,fp0			;cr*sp*-sy
		fmove		fp5,fp1
		fneg		fp1
		fmul		fp2,fp1			;sr*-cy
		fadd		fp1,fp0
		fmove.s		fp0,20(a1)		;=(sr*-cy)+(cr*sp*-sy)
		fmove.s		fp0,20(a0)
;right
		fmove		fp4,fp0
		fmul		fp3,fp0
		fmove		fp5,fp1
		fmul		fp6,fp1
		fmul		fp2,fp1
		fadd		fp1,fp0
		fmove.s		fp0,24(a1)
		fmul.s		_ProjScaleY,fp0
		fmove.s		fp0,24(a0)
		fmove		fp7,fp0
		fmul		fp2,fp0
		fmove.s		fp0,28(a1)
		fmul.s		_ProjScaleY,fp0
		fmove.s		fp0,28(a0)
		fmove		fp5,fp0
		fmul		fp3,fp0
		fmove		fp4,fp1
		fneg		fp1
		fmul		fp6,fp1
		fmul		fp2,fp1
		fadd		fp1,fp0
		fmove.s		fp0,32(a1)
		fmul.s		_ProjScaleY,fp0
		fmove.s		fp0,32(a0)

		move.l		#_ViewMatrix+36,a0
		move.l		#_MainMatrix+36,a1
		move.l		cam_PosX(a3),d0
		move.l		d0,(a0)+
		move.l		d0,(a1)+
		move.l		cam_PosY(a3),d0
		move.l		d0,(a0)+
		move.l		d0,(a1)+
		move.l		cam_PosZ(a3),d0
		move.l		d0,(a0)
		move.l		d0,(a1)

		move.l		#_ViewFrustrum,a0
		move.l		#_ViewMatrix+36,a1
		move.l		#_MainMatrix,a2

		fmove.s		#$bf800000,fp0
		fmove.s		#$3F800000,fp1
		fmove.s		#0,fp2
		bsr.s		_ComputePlane
		lea		pl_Sizeof(a0),a0
		fmove.s		#$3F800000,fp0
		fmove.s		#$3F800000,fp1
		fmove.s		#0,fp2
		bsr.s		_ComputePlane
		lea		pl_Sizeof(a0),a0
		fmove.s		#0,fp0
		fmove.s		#$3F800000,fp1
		fmove.s		#$3F800000,fp2
		bsr.s		_ComputePlane
		lea		pl_Sizeof(a0),a0
		fmove.s		#0,fp0
		fmove.s		#$3F800000,fp1
		fmove.s		#$bf800000,fp2
		bsr.s		_ComputePlane

		move.l		#_ViewMatrix,a0
		move.l		#_MViewMatrix,a1
		moveq		#12,d0
.CLoop		move.l		(a0)+,(a1)+
		subq.w		#1,d0
		bne.s		.CLoop

		fmovem		(sp)+,fp0-fp7
		movem.l		(a7)+,d0-d2/a1-a3
		rts

;---------------------------------------------------------------------
		XDEF		_ComputePlane
		cnop		0,4
_ComputePlane	fmove		fp0,fp3
		fmul.s		(a2),fp3
		fmove		fp1,fp4
		fmul.s		12(a2),fp4
		fadd		fp4,fp3
		fmove		fp2,fp4
		fmul.s		24(a2),fp4
		fadd		fp4,fp3
		fmove.s		fp3,pl_NormalX(a0)

		fmove		fp0,fp3
		fmul.s		4(a2),fp3
		fmove		fp1,fp4
		fmul.s		16(a2),fp4
		fadd		fp4,fp3
		fmove		fp2,fp4
		fmul.s		28(a2),fp4
		fadd		fp4,fp3
		fmove.s		fp3,pl_NormalY(a0)

		fmul.s		8(a2),fp0
		fmul.s		20(a2),fp1
		fadd		fp1,fp0
		fmul.s		32(a2),fp2
		fadd		fp2,fp0
		fmove.s		fp0,pl_NormalZ(a0)

		fmove.s		pl_NormalX(a0),fp0
		fmul.s		vc_X(a1),fp0
		fmove.s		pl_NormalY(a0),fp1
		fmul.s		vc_Y(a1),fp1
		fadd		fp1,fp0
		fmove.s		pl_NormalZ(a0),fp1
		fmul.s		vc_Z(a1),fp1
		fadd		fp1,fp0
		fmove.s		fp0,pl_Dist(a0)
		rts

_FDivisors		ds.l	18
_scan			ds.l	MAX_HEIGHT
_y			ds.w	1
_ey			ds.w	1




