; ---------------------------------------------------------------------------
; Author: Jacek (Noe) Cybularczyk / Total Vision Inc.
; (c) 1997 by Total Vision Inc.
; Licensed by Venus Art Entertainment
; ---------------------------------------------------------------------------

		INCLUDE	"exec/types.i"
		INCLUDE	"/TextureMapping/TM_structures.i"

CHUNKY_WIDTH    EQU     320
CHUNKY_HEIGHT   EQU     200

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

		XDEF	_RenderTxtEnvBumpFace
		XDEF	_RenderTxtEnvFace

		XREF	_ChunkyWidth
		XREF	_ChunkyAdr
		XREF	_TxtMapPtr
		XREF	_BumpMapPtr
		XREF	_EnvMapPtr
		XREF	_ShineLUTPtr
		XDEF	_BumpMapped

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

		SECTION	TextureMap_asm,CODE


; ---------------------------------------------------------------------------
; a0.l	pointer to FACE structure

_RenderTxtEnvBumpFace
		movem.l	d0-d7/a0-a6,-(sp)
		bsr.w	CalcRenderFaceParamsA
		bne.w	RTEBF_End

		movea.l	_EnvMapPtr,a1
		movea.l	_TxtMapPtr,a2
		movea.l	_ShineLUTPtr,a3
		movea.l	_BumpMapPtr,a5

		movea.l	(iuvstd1,pc),a0
		move.l	(iuvstd2,pc),d3
		move.l	(iuvstd3,pc),d4

		move.l	#1,section

		move.l	(ouvst1,pc),d0
		move.l	(ouvst2,pc),d1

		tst.l	d2
		bgt.w	RTEBF_0

		move.l	(ouvst3,pc),d2

		move.l	(xl,pc),d6
		move.l	(xs1,pc),d7
		bra.w	RTEBF_1
RTEBF_loop1
		swap	d6
		swap	d7
		sub.w	d6,d7
		lea	(a6,d6.w),a4

; d0.l	vv00UUuu	start values
; d1.l	tt0000VV	start values
; d2.l	SSss00TT	start values
; a0.l	vv00UUuu	delta values
; d3.l	tt0000VV	delta values
; d4.l	SSss00TT	delta values
; d7.w	loop counter (-1)

		move.w	d0,d5		; preload register for better pairing
RTEBF_loop0
		move.b	d1,d5
		move.l	d2,d6		; paired
		add.l	a0,d0
		swap	d6		; paired
		addx.l	d3,d1
		move.b	d2,d6		; paired
		addx.l	d4,d2
		add.w	(a5,d6.w*2),d5	; paired
		move.w	(a1,d5.w*2),d5
		move.b	(a2,d6.w),d5
		move.b	(a3,d5.l),(a4)+
		move.w	d0,d5

		dbra	d7,RTEBF_loop0	; paired

		adda.l	_ChunkyWidth,a6

		move.l	(ouvst1,pc),d0
		add.l	(ouvstd1,pc),d0
		move.l	d0,ouvst1
		move.l	(ouvst2,pc),d1
		move.l	(ouvstd2,pc),d2
		addx.l	d2,d1
		move.l	d1,ouvst2
		move.l	(ouvst3,pc),d2
		move.l	(ouvstd3,pc),d6
		addx.l	d6,d2
		move.l	d2,ouvst3

		move.l	(xl,pc),d6
		add.l	(dxl,pc),d6
		move.l	d6,xl

		move.l	(xs1,pc),d7
		add.l	(dxs1,pc),d7
		move.l	d7,xs1
RTEBF_1
		subq.l	#1,h1
		bpl.w	RTEBF_loop1

		tst.l	(section,pc)
		beq.b	RTEBF_End

		move.l	(xs2,pc),d7
		move.l	d7,xs1
		move.l	(dxs2,pc),dxs1
		move.l	(h2,pc),h1
		subq.l	#1,section

		bra.w	RTEBF_loop1

RTEBF_End
		movem.l	(sp)+,d0-d7/a0-a6
		rts

RTEBF_0
		move.l	(ouvst3,pc),d2

		move.l	(xs1,pc),d6
		move.l	(xl,pc),d7
		bra.w	RTEBF_2
RTEBF_loop3
		swap	d6
		swap	d7
		lea	(1.b,a6,d7.w),a4
		sub.w	d6,d7

; d0.l	vv00UUuu	start values
; d1.l	tt0000VV	start values
; d2.l	SSss00TT	start values
; a0.l	vv00UUuu	delta values
; d3.l	tt0000VV	delta values
; d4.l	SSss00TT	delta values
; d7.w	loop counter (-1)

		move.w	d0,d5		; preload register for better pairing
RTEBF_loop2
		move.b	d1,d5
		move.l	d2,d6		; paired
		sub.l	a0,d0
		swap	d6		; paired
		subx.l	d3,d1
		move.b	d2,d6		; paired
		subx.l	d4,d2
		add.w	(a5,d6.w*2),d5	; paired
		move.w	(a1,d5.w*2),d5
		move.b	(a2,d6.w),d5
		move.b	(a3,d5.l),-(a4)
		move.w	d0,d5

		dbra	d7,RTEBF_loop2	; paired

		adda.l	_ChunkyWidth,a6

		move.l	(ouvst1,pc),d0
		add.l	(ouvstd1,pc),d0
		move.l	d0,ouvst1
		move.l	(ouvst2,pc),d1
		move.l	(ouvstd2,pc),d2
		addx.l	d2,d1
		move.l	d1,ouvst2
		move.l	(ouvst3,pc),d2
		move.l	(ouvstd3,pc),d6
		addx.l	d6,d2
		move.l	d2,ouvst3

		move.l	(xs1,pc),d6
		add.l	(dxs1,pc),d6
		move.l	d6,xs1

		move.l	(xl,pc),d7
		add.l	(dxl,pc),d7
		move.l	d7,xl
RTEBF_2
		subq.l	#1,h1
		bpl.w	RTEBF_loop3

		tst.l	(section,pc)
		beq.w	RTEBF_End

		move.l	(xs2,pc),d6
		move.l	d6,xs1
		move.l	(dxs2,pc),dxs1
		move.l	(h2,pc),h1
		subq.l	#1,section

		bra.w	RTEBF_loop3


; ---------------------------------------------------------------------------
; a0.l	pointer to FACE structure

_RenderTxtEnvFace
		movem.l	d0-d7/a0-a6,-(sp)

		bsr.w	CalcRenderFaceParamsA
		bne.w	RTEF_End

		movea.l	_EnvMapPtr,a1
		movea.l	_TxtMapPtr,a2
		movea.l	_ShineLUTPtr,a3

		movea.l	(iuvstd1,pc),a0
		move.l	(iuvstd2,pc),d3
		move.l	(iuvstd3,pc),d4

		move.l	#1,section

		move.l	(ouvst1,pc),d0
		move.l	(ouvst2,pc),d1

		tst.l	d2
		bgt.w	RTEF_0

		move.l	(ouvst3,pc),d2

		move.l	(xl,pc),d6
		move.l	(xs1,pc),d7
		bra.w	RTEF_1
RTEF_loop1
		swap	d6
		swap	d7
		sub.w	d6,d7
		lea	(a6,d6.w),a4

; d0.l	vv00UUuu	start values
; d1.l	tt0000VV	start values
; d2.l	SSss00TT	start values
; a0.l	vv00UUuu	delta values
; d3.l	tt0000VV	delta values
; d4.l	SSss00TT	delta values
; d7.w	loop counter (-1)

		move.w	d0,d5		; preload register for better pairing
RTEF_loop0
		move.b	d1,d5
		add.l	a0,d0		; paired
		move.w	(a1,d5.w*2),d5
		move.l	d2,d6		; paired
		addx.l	d3,d1
		swap	d6		; paired
		move.b	d2,d6
		move.b	(a2,d6.w),d5
		addx.l	d4,d2		; paired
		move.b	(a3,d5.l),(a4)+
		move.w	d0,d5

		dbra	d7,RTEF_loop0	; paired

		adda.l	_ChunkyWidth,a6

		move.l	(ouvst1,pc),d0
		add.l	(ouvstd1,pc),d0
		move.l	d0,ouvst1
		move.l	(ouvst2,pc),d1
		move.l	(ouvstd2,pc),d2
		addx.l	d2,d1
		move.l	d1,ouvst2
		move.l	(ouvst3,pc),d2
		move.l	(ouvstd3,pc),d6
		addx.l	d6,d2
		move.l	d2,ouvst3

		move.l	(xl,pc),d6
		add.l	(dxl,pc),d6
		move.l	d6,xl

		move.l	(xs1,pc),d7
		add.l	(dxs1,pc),d7
		move.l	d7,xs1
RTEF_1
		subq.l	#1,h1
		bpl.w	RTEF_loop1

		tst.l	(section,pc)
		beq.b	RTEF_End

		move.l	(xs2,pc),d7
		move.l	d7,xs1
		move.l	(dxs2,pc),dxs1
		move.l	(h2,pc),h1
		subq.l	#1,section

		bra.w	RTEF_loop1

RTEF_End
		movem.l	(sp)+,d0-d7/a0-a6
		rts

RTEF_0
		move.l	(ouvst3,pc),d2

		move.l	(xs1,pc),d6
		move.l	(xl,pc),d7
		bra.w	RTEF_2
RTEF_loop3
		swap	d6
		swap	d7
		lea	(1.b,a6,d7.w),a4
		sub.w	d6,d7

; d0.l	vv00UUuu	start values
; d1.l	tt0000VV	start values
; d2.l	SSss00TT	start values
; a0.l	vv00UUuu	delta values
; d3.l	tt0000VV	delta values
; d4.l	SSss00TT	delta values
; d7.w	loop counter (-1)

		move.w	d0,d5		; preload register for better pairing
RTEF_loop2
		move.b	d1,d5
		sub.l	a0,d0		; paired
		move.w	(a1,d5.w*2),d5
		move.l	d2,d6		; paired
		subx.l	d3,d1
		swap	d6		; paired
		move.b	d2,d6
		move.b	(a2,d6.w),d5
		subx.l	d4,d2		; paired
		move.b	(a3,d5.l),-(a4)
		move.w	d0,d5

		dbra	d7,RTEF_loop2	; paired

		adda.l	_ChunkyWidth,a6

		move.l	(ouvst1,pc),d0
		add.l	(ouvstd1,pc),d0
		move.l	d0,ouvst1
		move.l	(ouvst2,pc),d1
		move.l	(ouvstd2,pc),d2
		addx.l	d2,d1
		move.l	d1,ouvst2
		move.l	(ouvst3,pc),d2
		move.l	(ouvstd3,pc),d6
		addx.l	d6,d2
		move.l	d2,ouvst3

		move.l	(xs1,pc),d6
		add.l	(dxs1,pc),d6
		move.l	d6,xs1

		move.l	(xl,pc),d7
		add.l	(dxl,pc),d7
		move.l	d7,xl
RTEF_2
		subq.l	#1,h1
		bpl.w	RTEF_loop3

		tst.l	(section,pc)
		beq.w	RTEF_End

		move.l	(xs2,pc),d6
		move.l	d6,xs1
		move.l	(dxs2,pc),dxs1
		move.l	(h2,pc),h1
		subq.l	#1,section

		bra.w	RTEF_loop3

; ---------------------------------------------------------------------------
; local data section

		CNOP	0,4

ouvst1		DC.L	0
ouvst2		DC.L	0
ouvst3		DC.L	0

ouvstd1		DC.L	0
ouvstd2		DC.L	0
ouvstd3		DC.L	0

iuvstd1		DC.L	0
iuvstd2		DC.L	0
iuvstd3		DC.L	0

xl		DC.L	0
xs1		DC.L	0
xs2		DC.L	0

dxl		DC.L	0
dxs1		DC.L	0
dxs2		DC.L	0

h1		DC.L	0
h2		DC.L	0
section		DC.L	0


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

CONV_UVST	MACRO	; dr0, dr1, dr2, dr3
		swap	\3	; SSss0000
		ror.l	#8,\4	; tt0000TT
		move.w	\4,\3	; SSss00TT	ok
		swap	\1	; UUuu0000
		lsl.l	#8,\2	; 00VVvv00
		move.w	\2,\1	; UUuuvv00
		swap	\1	; vv00UUuu	ok
		swap	\4	; 00TTtt00
		move.w	\4,\2	; 00VVtt00
		swap	\2	; tt0000VV	ok
		ENDM	; dr0, dr1, dr2

; ---------------------------------------------------------------------------
; a0.l	pointer to FACE structure

CalcRenderFaceParamsA

		move.l	(a0,fc_V1),a1
		move.l	(a0,fc_V2),a2
		move.l	(a0,fc_V3),a3

; move texture uv positions to temporary locations in vertices

                cmp.l   #0,ClipFlag
                bne.b   CRFP_clip

		move.l	(a0,fc_u1),(a1,vt_ut)
		move.l	(a0,fc_v1),(a1,vt_vt)
		move.l	(a0,fc_u2),(a2,vt_ut)
		move.l	(a0,fc_v2),(a2,vt_vt)
		move.l	(a0,fc_u3),(a3,vt_ut)
		move.l	(a0,fc_v3),(a3,vt_vt)
CRFP_clip
; a1.l	pointer to V1
; a2.l	pointer to V2
; a3.l	pointer to V3

; sorting vertices (simillary to buble[gum] sort)

		move.l	(a2,vt_yp),d0
		cmp.l	(a1,vt_yp),d0
		bge.b	CRFP_0

		exg	a1,a2
		move.l	(a2,vt_yp),d0
CRFP_0
		cmp.l	(a3,vt_yp),d0
		ble.b	CRFP_1

		exg	a2,a3

		move.l	(a2,vt_yp),d0
		cmp.l	(a1,vt_yp),d0
		bge.b	CRFP_1

		exg	a1,a2
CRFP_1
		move.l	(a3,vt_yp),d0
		sub.l	(a1,vt_yp),d0
		beq.w	CRFP_End

; d0.l	y3-y1

		move.l	(a2,vt_yp),d1
		sub.l	(a1,vt_yp),d1
		asl.l	#8,d1
		divs.l	d0,d1

; d1.l	temp (24.8)

		move.l	(a3,vt_xp),d2
		sub.l	(a1,vt_xp),d2
		muls.w	d1,d2			;muls.l	d1,d2
		asr.l	#8,d2
		sub.l	(a2,vt_xp),d2
		add.l	(a1,vt_xp),d2
		beq.w	CRFP_End

; d2.l	maxwidth

		move.l	(a3,vt_u),d3
		sub.l	(a1,vt_u),d3
		movea.l	d3,a0
		muls.w	d1,d3			;muls.l	d1,d3
		move.l	(a2,vt_u),d4
		sub.l	(a1,vt_u),d4
		asl.l	#8,d4
		sub.l	d4,d3
		divs.l	d2,d3

; d3.l	idu (24.8)
; a0.l	u3-u1

		move.l	(a3,vt_v),d4
		sub.l	(a1,vt_v),d4
		movea.l	d4,a4
		muls.w	d1,d4			;muls.l	d1,d4
		move.l	(a2,vt_v),d5
		sub.l	(a1,vt_v),d5
		asl.l	#8,d5
		sub.l	d5,d4
		divs.l	d2,d4

; d4.l	idv (24.8)
; a4.l	v3-v1

		move.l	(a3,vt_ut),d5
		sub.l	(a1,vt_ut),d5
		movea.l	d5,a5
		muls.w	d1,d5			;muls.l	d1,d5
		move.l	(a2,vt_ut),d6
		sub.l	(a1,vt_ut),d6
		asl.l	#8,d6
		sub.l	d6,d5
		divs.l	d2,d5

; d5.l	idut (24.8)
; a5.l	ut3-ut1

		move.l	(a3,vt_vt),d6
		sub.l	(a1,vt_vt),d6
		movea.l	d6,a6
		muls.w	d1,d6			;muls.l	d1,d6
		move.l	(a2,vt_vt),d7
		sub.l	(a1,vt_vt),d7
		asl.l	#8,d7
		sub.l	d7,d6
		divs.l	d2,d6

; d6.l	idvt (24.8)
; a6.l	vt3-vt1

; convert idu idv idut idvt -> vv00UUuu tt0000VV SSss00TT

		CONV_UVST	d3,d4,d5,d6

		move.l	d3,iuvstd1
		move.l	d4,iuvstd2
		move.l	d5,iuvstd3

; iuvstd1.l	vv00UUuu
; iuvstd2.l	tt0000VV
; iuvstd3.l	SSss00TT

		move.l	a0,d3
		asl.l	#8,d3
		divs.l	d0,d3
		addq	#1,d3

; d3.l	odu (24.8)

		move.l	a4,d4
		asl.l	#8,d4
		divs.l	d0,d4
		addq	#1,d4

; d4.l	odv (24.8)

		move.l	a5,d5
		asl.l	#8,d5
		divs.l	d0,d5
		addq	#1,d5

; d5.l	odut (24.8)

		move.l	a6,d6
		asl.l	#8,d6
		divs.l	d0,d6
		addq	#1,d6

; d6.l	odvt (24.8)

; convert odu odv odut odvt -> vv00UUuu tt0000VV SSss00TT

		CONV_UVST	d3,d4,d5,d6

		move.l	d3,ouvstd1
		move.l	d4,ouvstd2
		move.l	d5,ouvstd3

; ouvstd1.l	vv00UUuu
; ouvstd2.l	tt0000VV
; ouvstd3.l	SSss00TT

		move.l	(a3,vt_xp),d3
		sub.l	(a1,vt_xp),d3
		swap	d3
		clr.w	d3
		divs.l	d0,d3
		addq	#1,d3
		move.l	d3,dxl

; dxl.l	delta of longnest span (16.16)

		moveq	#0,d3
		move.l	(a2,vt_yp),d0
		sub.l	(a1,vt_yp),d0
		beq.b	CRFP_2
		move.l	(a2,vt_xp),d3
		sub.l	(a1,vt_xp),d3
		swap	d3
		clr.w	d3
		divs.l	d0,d3
		addq	#1,d3
CRFP_2
		move.l	d0,h1
		move.l	d3,dxs1

; dxs1.l	delta of first shortnest span (16.16)
; h1.l	y2-y1

		moveq	#0,d3
		move.l	(a3,vt_yp),d0
		sub.l	(a2,vt_yp),d0
		beq.b	CRFP_3
		move.l	(a3,vt_xp),d3
		sub.l	(a2,vt_xp),d3
		swap	d3
		clr.w	d3
		divs.l	d0,d3
		addq	#1,d3
CRFP_3
		move.l	d0,h2
		move.l	d3,dxs2

; dxs2.l	delta of second shortnest span (16.16)
; h2.l	y3-y2

		move.l	(a1,vt_xp),d3
		swap	d3
		clr.w	d3
		move.l	d3,xl
		move.l	d3,xs1

; xl.l	longnest x
; xs1.l	first shortnest x

		move.l	(a2,vt_xp),d3
		swap	d3
		clr.w	d3
		move.l	d3,xs2

; xs2.l	second shortnest x

		move.l	(a1,vt_u),d3
		asl.l	#8,d3
		move.l	(a1,vt_v),d4
		asl.l	#8,d4
		move.l	(a1,vt_ut),d5
		asl.l	#8,d5
		move.l	(a1,vt_vt),d6
		asl.l	#8,d6

; convert u v ut vt -> vv00UUuu tt0000VV SSss00TT

		CONV_UVST	d3,d4,d5,d6

		move.l	d3,ouvst1
		move.l	d4,ouvst2
		move.l	d5,ouvst3

; ouvst1.l	vv00UUuu
; ouvst2.l	tt0000VV
; ouvst3.l	SSss00TT

		move.l	(a1,vt_yp),d3
		mulu.w	_ChunkyWidth+2,d3	;mulu.l	_ChunkyWidth,d3
		movea.l	_ChunkyAdr,a6
		lea	(a6,d3.l),a6

		moveq	#0,d5
		rts

CRFP_End
		moveq	#1,d5
		rts

;========================================================================================================
ClipParams
		sub.l	d1,d5
		muls.w	d3,d5
		divs.w	d6,d5
		ext.l	d5
		sub.l	d5,d1
		rts

ClipParams2
		sub.l	d2,d5
		muls.w	d3,d5
		divs.w	d6,d5
		ext.l	d5
		sub.l	d5,d2
		rts

ClipParams3
		sub.l	d1,d5
		muls.w	d4,d5
		divs.w	d2,d5
		ext.l	d5
		sub.l	d5,d1
		rts

ClipParams4
		sub.l	d2,d5
		muls.w	d4,d5
		divs.w	d1,d5
		ext.l	d5
		sub.l	d5,d2
		rts

		XDEF	_BM_RenderVClipFace

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
; a0.l	pointer to FACE

_BM_RenderVClipFace
		movem.l	d2-d7/a2-a6,-(sp)

		move.l	(a0,fc_V1),a1
		move.l	(a0,fc_V2),a2
		move.l	(a0,fc_V3),a3
		move.l	(a0,fc_u1),(a1,vt_ut)
		move.l	(a0,fc_v1),(a1,vt_vt)
		move.l	(a0,fc_u2),(a2,vt_ut)
		move.l	(a0,fc_v2),(a2,vt_vt)
		move.l	(a0,fc_u3),(a3,vt_ut)
		move.l	(a0,fc_v3),(a3,vt_vt)

                move.l  #0,ClipFlag

		lea	BM_tmpVertices,a3
		moveq	#-2,d7

		move.l	(a0,fc_V1),a1
		move.l	(a0,fc_V2),a2
		bsr.w	BM_rcf_VClipEdge

		move.l	(a0,fc_V2),a1
		move.l	(a0,fc_V3),a2
		bsr.b	BM_rcf_VClipEdge

		move.l	(a0,fc_V3),a1
		move.l	(a0,fc_V1),a2
		bsr.b	BM_rcf_VClipEdge

		tst.w	d7
		bmi.b	BM_rcf0

		lea	BM_tmpVertices,a3
		lea	BM_tmpcVertices,a4
		moveq	#-3,d6

BM_rcf_Loop0	move.l	a3,a1
		lea	(a3,vt_SIZEOF),a3
		move.l	a3,a2
		bsr.w	BM_rcf_HClipEdge

		dbra	d7,BM_rcf_Loop0

		move.l	a3,a1
		lea	BM_tmpVertices,a2
		bsr.w	BM_rcf_HClipEdge

		tst.w	d6
		bmi.b	BM_rcf0

		move.l	(a0,fc_Flags),d2
		lea	(pc,BM_cFaces),a2

BM_rcf_Loop1	move.l	a2,a0
		move.l	d2,(a0,fc_Flags)
                move.l  #1,ClipFlag

		tst.l	_BumpMapped
		beq.b	NoBumpMapped
		bsr.w	_RenderTxtEnvBumpFace
		bra.b	done
NoBumpMapped
		bsr.w	_RenderTxtEnvFace
done
                move.l  #0,ClipFlag
		lea	(a2,fc_SIZEOF),a2

		dbra	d6,BM_rcf_Loop1
BM_rcf0
		movem.l	(sp)+,d2-d7/a2-a6
		rts

; d7.w	vertices counter (updates)
; a0.l	-=- SAVED -=-
; a1.l	pointer to V1
; a2.l	pointer to V2
; a3.l	pointer to current temporary VERTEX (updates)

BM_rcf_VClipEdge

		move.l	(a1,vt_ClipBits),d0
		and.l	(a2,vt_ClipBits),d0
		andi.w	#LEFT_VCLIP_FLAG|RIGHT_VCLIP_FLAG,d0
		beq.b	BM_rcf_vce4

		rts

BM_rcf_vce4

; clip V1
		move.l	(a1,vt_ClipBits),d0
		move.l	(a1,vt_xp),d3
		move.l	(a1,vt_yp),d4
		btst	#LEFT_VCLIP_BIT,d0
		beq.w	BM_rcf_vce0

; V1 left clipped

		move.l	(a2,vt_xp),d6
		sub.l	d3,d6

		move.l	(a2,vt_yp),d5
		sub.l	d4,d5
		muls.w	d3,d5
		divs.w	d6,d5
		ext.l	d5
		sub.l	d5,d4
		
		move.l	(a1,vt_u),d1
		move.l	(a2,vt_u),d5
		bsr.w	ClipParams
		move.l	d1,(a3,vt_u)

		move.l	(a1,vt_v),d1
		move.l	(a2,vt_v),d5
		bsr.w	ClipParams
		move.l	d1,(a3,vt_v)


		move.l	(a1,vt_ut),d1
		move.l	(a2,vt_ut),d5
		bsr.w	ClipParams
		move.l	d1,(a3,vt_ut)

		move.l	(a1,vt_vt),d1
		move.l	(a2,vt_vt),d5
		bsr.w	ClipParams
		move.l	d1,(a3,vt_vt)

		moveq	#0,d3

		andi.w	#LEFT_VCLIP_FLAG|RIGHT_VCLIP_FLAG,d0
		tst.l	d4
		bpl.b	BM_rcf_vce10
		bset	#TOP_VCLIP_BIT,d0
		bra.w	BM_rcf_vce1a
BM_rcf_vce10
		cmpi.l	#CHUNKY_HEIGHT,d4
		blt.w	BM_rcf_vce1a
		bset	#BOTTOM_VCLIP_BIT,d0
		bra.w	BM_rcf_vce1a

BM_rcf_vce0	btst	#RIGHT_VCLIP_BIT,d0
		beq.w	BM_rcf_vce1

; V1 right clipped

		move.l	(a2,vt_xp),d6
		sub.l	d3,d6

		subi.l	#CHUNKY_WIDTH-1,d3

		move.l	(a2,vt_yp),d5
		sub.l	d4,d5
		muls.w	d3,d5
		divs.w	d6,d5
		ext.l	d5
		sub.l	d5,d4

		move.l	(a1,vt_u),d1
		move.l	(a2,vt_u),d5
		bsr.w	ClipParams
		move.l	d1,(a3,vt_u)

		move.l	(a1,vt_v),d1
		move.l	(a2,vt_v),d5
		bsr.w	ClipParams
		move.l	d1,(a3,vt_v)

		move.l	(a1,vt_ut),d1
		move.l	(a2,vt_ut),d5
		bsr.w	ClipParams
		move.l	d1,(a3,vt_ut)

		move.l	(a1,vt_vt),d1
		move.l	(a2,vt_vt),d5
		bsr.w	ClipParams
		move.l	d1,(a3,vt_vt)

		move.l	#CHUNKY_WIDTH-1,d3

		andi.w	#LEFT_VCLIP_FLAG|RIGHT_VCLIP_FLAG,d0
		tst.l	d4
		bpl.b	BM_rcf_vce5
		bset	#TOP_VCLIP_BIT,d0
		bra.b	BM_rcf_vce1a
BM_rcf_vce5
		cmpi.l	#CHUNKY_HEIGHT,d4
		blt.b	BM_rcf_vce1a
		bset	#BOTTOM_VCLIP_BIT,d0
		bra.b	BM_rcf_vce1a

BM_rcf_vce1

; V1 not clipped (only save vertex)
		move.l	(a1,vt_u),(a3,vt_u)
		move.l	(a1,vt_v),(a3,vt_v)
		move.l	(a1,vt_ut),(a3,vt_ut)
		move.l	(a1,vt_vt),(a3,vt_vt)
BM_rcf_vce1a
		move.l	d3,(a3,vt_xp)
		move.l	d4,(a3,vt_yp)
		move.l	d0,(a3,vt_ClipBits)
		lea	(a3,vt_SIZEOF),a3
		addq.w	#1,d7

; clip V2
		move.l	(a2,vt_ClipBits),d0
		btst	#LEFT_VCLIP_BIT,d0
		beq.w	BM_rcf_vce2

; V2 left clipped

		move.l	(a2,vt_xp),d3
		move.l	(a2,vt_yp),d4

		move.l	(a1,vt_xp),d6
		sub.l	d3,d6

		move.l	(a1,vt_yp),d5
		sub.l	d4,d5
		muls.w	d3,d5
		divs.w	d6,d5
		ext.l	d5
		sub.l	d5,d4

		move.l	(a1,vt_u),d5
		move.l	(a2,vt_u),d2
		bsr.w	ClipParams2
		move.l	d2,(a3,vt_u)

		move.l	(a1,vt_v),d5
		move.l	(a2,vt_v),d2
		bsr.w	ClipParams2
		move.l	d2,(a3,vt_v)

		move.l	(a1,vt_ut),d5
		move.l	(a2,vt_ut),d2
		bsr.w	ClipParams2
		move.l	d2,(a3,vt_ut)

		move.l	(a1,vt_vt),d5
		move.l	(a2,vt_vt),d2
		bsr.w	ClipParams2
		move.l	d2,(a3,vt_vt)

		moveq	#0,d3

		andi.w	#LEFT_VCLIP_FLAG|RIGHT_VCLIP_FLAG,d0
		tst.l	d4
		bpl.b	BM_rcf_vce6
		bset	#TOP_VCLIP_BIT,d0
		bra.b	BM_rcf_vce7
BM_rcf_vce6
		cmpi.l	#CHUNKY_HEIGHT,d4
		blt.b	BM_rcf_vce7
		bset	#BOTTOM_VCLIP_BIT,d0
BM_rcf_vce7
		move.l	d3,(a3,vt_xp)
		move.l	d4,(a3,vt_yp)
		move.l	d0,(a3,vt_ClipBits)
		lea	(a3,vt_SIZEOF),a3
		addq.w	#1,d7

		rts

BM_rcf_vce2	btst	#RIGHT_VCLIP_BIT,d0
		beq.w	BM_rcf_vce3

; V2 right clipped

		move.l	(a2,vt_xp),d3
		move.l	(a2,vt_yp),d4

		move.l	(a1,vt_xp),d6
		sub.l	d3,d6

		subi.l	#CHUNKY_WIDTH-1,d3

		move.l	(a1,vt_yp),d5
		sub.l	d4,d5
		muls.w	d3,d5
		divs.w	d6,d5
		ext.l	d5
		sub.l	d5,d4

		move.l	(a1,vt_u),d5
		move.l	(a2,vt_u),d2
		bsr.w	ClipParams2
		move.l	d2,(a3,vt_u)

		move.l	(a1,vt_v),d5
		move.l	(a2,vt_v),d2
		bsr.w	ClipParams2
		move.l	d2,(a3,vt_v)

		move.l	(a1,vt_ut),d5
		move.l	(a2,vt_ut),d2
		bsr.w	ClipParams2
		move.l	d2,(a3,vt_ut)

		move.l	(a1,vt_vt),d5
		move.l	(a2,vt_vt),d2
		bsr.w	ClipParams2
		move.l	d2,(a3,vt_vt)

		andi.w	#LEFT_VCLIP_FLAG|RIGHT_VCLIP_FLAG,d0
		tst.l	d4
		bpl.b	BM_rcf_vce8
		bset	#TOP_VCLIP_BIT,d0
		bra.b	BM_rcf_vce9
BM_rcf_vce8
		cmpi.l	#CHUNKY_HEIGHT,d4
		blt.b	BM_rcf_vce9
		bset	#BOTTOM_VCLIP_BIT,d0
BM_rcf_vce9
		move.l	#CHUNKY_WIDTH-1,(a3,vt_xp)
		move.l	d4,(a3,vt_yp)
		move.l	d0,(a3,vt_ClipBits)
		lea	(a3,vt_SIZEOF),a3
		addq.w	#1,d7

BM_rcf_vce3

; V2 not clipped

		rts

; d6.w	vertices counter (updates)
; d7.w	-=- SAVED -=-
; a0.l	-=- SAVED -=-
; a1.l	pointer to V1
; a2.l	pointer to V2
; a3.l	-=- SAVED -=-
; a4.l	pointer to current temporary VERTEX (updates)

BM_rcf_HClipEdge

		move.l	(a1,vt_ClipBits),d0
		and.l	(a2,vt_ClipBits),d0
		andi.w	#TOP_VCLIP_FLAG|BOTTOM_VCLIP_FLAG,d0
		beq.b	BM_rcf_hce4

		rts

BM_rcf_hce4

; clip V1
		move.l	(a1,vt_ClipBits),d0
		move.l	(a1,vt_xp),d3
		move.l	(a1,vt_yp),d4
		btst	#TOP_VCLIP_BIT,d0
		beq.b	BM_rcf_hce0

; V1 top clipped

		move.l	(a2,vt_yp),d2
		sub.l	d4,d2

		move.l	(a2,vt_xp),d5
		sub.l	d3,d5
		muls.w	d4,d5
		divs.w	d2,d5
		ext.l	d5
		sub.l	d5,d3

		move.l	(a1,vt_u),d1
		move.l	(a2,vt_u),d5
		bsr.w	ClipParams3
		move.l	d1,(a4,vt_u)

		move.l	(a1,vt_v),d1
		move.l	(a2,vt_v),d5
		bsr.w	ClipParams3
		move.l	d1,(a4,vt_v)

		move.l	(a1,vt_ut),d1
		move.l	(a2,vt_ut),d5
		bsr.w	ClipParams3
		move.l	d1,(a4,vt_ut)

		move.l	(a1,vt_vt),d1
		move.l	(a2,vt_vt),d5
		bsr.w	ClipParams3
		move.l	d1,(a4,vt_vt)

		moveq	#0,d4

		bra.w	BM_rcf_hce1a

BM_rcf_hce0	btst	#BOTTOM_VCLIP_BIT,d0
		beq.b	BM_rcf_hce1

; V1 bottom clipped

		move.l	(a2,vt_yp),d2
		sub.l	d4,d2

		subi.l	#CHUNKY_HEIGHT-1,d4

		move.l	(a2,vt_xp),d5
		sub.l	d3,d5
		muls.w	d4,d5
		divs.w	d2,d5
		ext.l	d5
		sub.l	d5,d3

		move.l	(a1,vt_u),d1
		move.l	(a2,vt_u),d5
		bsr.w	ClipParams3
		move.l	d1,(a4,vt_u)

		move.l	(a1,vt_v),d1
		move.l	(a2,vt_v),d5
		bsr.w	ClipParams3
		move.l	d1,(a4,vt_v)

		move.l	(a1,vt_ut),d1
		move.l	(a2,vt_ut),d5
		bsr.w	ClipParams3
		move.l	d1,(a4,vt_ut)

		move.l	(a1,vt_vt),d1
		move.l	(a2,vt_vt),d5
		bsr.w	ClipParams3
		move.l	d1,(a4,vt_vt)

		move.l	#CHUNKY_HEIGHT-1,d4
		bra.b	BM_rcf_hce1a

BM_rcf_hce1

; V1 not clipped (only save vertex)

		move.l	(a1,vt_u),(a4,vt_u)
		move.l	(a1,vt_v),(a4,vt_v)
		move.l	(a1,vt_ut),(a4,vt_ut)
		move.l	(a1,vt_vt),(a4,vt_vt)
BM_rcf_hce1a
		move.l	d3,(a4,vt_xp)
		move.l	d4,(a4,vt_yp)
		lea	(a4,vt_SIZEOF),a4
		addq.w	#1,d6

; clip V2
		move.l	(a2,vt_ClipBits),d0
		btst	#TOP_VCLIP_BIT,d0
		beq.w	BM_rcf_hce2

; V2 top clipped

		move.l	(a2,vt_xp),d3
		move.l	(a2,vt_yp),d4

		move.l	(a1,vt_yp),d1
		sub.l	d4,d1

		move.l	(a1,vt_xp),d5
		sub.l	d3,d5
		muls.w	d4,d5
		divs.w	d1,d5
		ext.l	d5
		sub.l	d5,d3

		move.l	(a1,vt_u),d5
		move.l	(a2,vt_u),d2
		bsr.w	ClipParams4
		move.l	d2,(a4,vt_u)

		move.l	(a1,vt_v),d5
		move.l	(a2,vt_v),d2
		bsr.w	ClipParams4
		move.l	d2,(a4,vt_v)

		move.l	(a1,vt_ut),d5
		move.l	(a2,vt_ut),d2
		bsr.w	ClipParams4
		move.l	d2,(a4,vt_ut)

		move.l	(a1,vt_vt),d5
		move.l	(a2,vt_vt),d2
		bsr.w	ClipParams4
		move.l	d2,(a4,vt_vt)

		moveq	#0,d4

		move.l	d3,(a4,vt_xp)
		move.l	d4,(a4,vt_yp)
		lea	(a4,vt_SIZEOF),a4
		addq.w	#1,d6
BM_rcf_hce3a
		rts

BM_rcf_hce2	btst	#BOTTOM_VCLIP_BIT,d0
		beq.w	BM_rcf_hce3

; V2 bottom clipped

		move.l	(a2,vt_xp),d3
		move.l	(a2,vt_yp),d4

		move.l	(a1,vt_yp),d1
		sub.l	d4,d1

		subi.l	#CHUNKY_HEIGHT-1,d4

		move.l	(a1,vt_xp),d5
		sub.l	d3,d5
		muls.w	d4,d5
		divs.w	d1,d5
		ext.l	d5
		sub.l	d5,d3

		move.l	(a1,vt_u),d5
		move.l	(a2,vt_u),d2
		bsr.w	ClipParams4
		move.l	d2,(a4,vt_u)

		move.l	(a1,vt_v),d5
		move.l	(a2,vt_v),d2
		bsr.w	ClipParams4
		move.l	d2,(a4,vt_v)


		move.l	(a1,vt_ut),d5
		move.l	(a2,vt_ut),d2
		bsr.w	ClipParams4
		move.l	d2,(a4,vt_ut)

		move.l	(a1,vt_vt),d5
		move.l	(a2,vt_vt),d2
		bsr.w	ClipParams4
		move.l	d2,(a4,vt_vt)

		move.l	d3,(a4,vt_xp)
		move.l	#CHUNKY_HEIGHT-1,(a4,vt_yp)
		lea	(a4,vt_SIZEOF),a4
		addq.w	#1,d6

BM_rcf_hce3

; V2 not clipped

		rts

		CNOP	0,4

BM_cFaces
BM_cFace1	DC.L	BM_cVertex1,BM_cVertex2,BM_cVertex3
		DCB.B	fc_SIZEOF-3*4
BM_cFace2	DC.L	BM_cVertex1,BM_cVertex3,BM_cVertex4
		DCB.B	fc_SIZEOF-3*4
BM_cFace3	DC.L	BM_cVertex1,BM_cVertex4,BM_cVertex5
		DCB.B	fc_SIZEOF-3*4
BM_cFace4	DC.L	BM_cVertex1,BM_cVertex5,BM_cVertex6
		DCB.B	fc_SIZEOF-3*4
BM_cFace5	DC.L	BM_cVertex1,BM_cVertex6,BM_cVertex7
		DCB.B	fc_SIZEOF-3*4
ClipFlag        dc.l    0
_BumpMapped	dc.l	0


                SECTION vert,bss
BM_tmpVertices	DCB.B	7*vt_SIZEOF

BM_tmpcVertices
BM_cVertex1	DCB.B	vt_SIZEOF
BM_cVertex2	DCB.B	vt_SIZEOF
BM_cVertex3	DCB.B	vt_SIZEOF
BM_cVertex4	DCB.B	vt_SIZEOF
BM_cVertex5	DCB.B	vt_SIZEOF
BM_cVertex6	DCB.B	vt_SIZEOF
BM_cVertex7	DCB.B	vt_SIZEOF
		END
