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

		INCLUDE	"exec/types.i"

		INCLUDE	"/Shared/SH_view.i"
		INCLUDE	"TM_const.i"
		INCLUDE	"TM_structures.i"

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

_SAFE		EQU	0
_SAFE_DEBUG	EQU	0
 
CHUNKY_WIDTH	EQU	320
CHUNKY_HEIGHT	EQU	200
CHUNKY_WIDTH2	EQU	CHUNKY_WIDTH>>1
CHUNKY_HEIGHT2	EQU	CHUNKY_HEIGHT>>1

COSINE_OFFSET	EQU	VALUES_NUMBER*(ANGLES_NUMBER>>2)*2

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

		XREF	_ChunkyWidth
		XREF	_ChunkyAdr
		XREF	_TxtMapPtr
		XREF	_BumpMapPtr
		XREF	_EnvMapPtr
		XREF	_ShineLUTPtr

		XREF	_TM_RotateTable
		XREF	_TM_PerspectiveTable
		XREF	_TM_ArcSineTable

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

		XDEF	_RenderFace

		XDEF	_TM_TransformObjectI
		XDEF	_TM_TransformObjectII
		XDEF	_TM_CreateDepthBuffer
		XDEF	_TM_SortDepthBuffer

;		XDEF	_tmp
;		XDEF	_dxl
;		XDEF	_dxs1
;		XDEF	_dxs2

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл

		SECTION	TM_render,CODE

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

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

; move texture uv positions to temporary locations in vertices

		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)

		btst	#FB_VCLIP-8,(a0,fc_Flags+2)
		bne.w	RenderVClipFace
RenderFace2
		move.l	(a0,fc_Flags),d0
		andi.l	#FF_TEXTURE|FF_ENVIRONMENT|FF_BUMP,d0

		cmpi.l	#FF_TEXTURE|FF_ENVIRONMENT|FF_BUMP,d0
		beq.b	RenderTxtEnvBumpFace

		cmpi.l	#FF_TEXTURE|FF_ENVIRONMENT,d0
		beq.w	RenderTxtEnvFace

		cmpi.l	#FF_TEXTURE,d0
		beq.w	RenderTxtFace

		cmpi.l	#FF_ENVIRONMENT,d0
		beq.w	RenderEnvFace

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


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

RenderTxtEnvBumpFace
		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
		move.l	(ouvst3,pc),d2

		tst.l	d6
		bpl.w	RTEBF_0

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

		IF	_SAFE
		bpl.b	RTEBF_huj1	; !!!
;		IF	_SAFE_DEBUG
;		illegal
;		ENDC
		moveq	#0,d7		; !!!
RTEBF_huj1				; !!!
		ENDC

		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	(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

		IF	_SAFE
		bpl.b	RTEBF_huj2	; !!!
;		IF	_SAFE_DEBUG
;		illegal
;		ENDC
		moveq	#0,d7		; !!!
RTEBF_huj2				; !!!
		ENDC

; 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
		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
		move.l	(ouvst3,pc),d2

		tst.l	d6
		bpl.w	RTEF_0

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

		IF	_SAFE
		bpl.b	RTEF_huj1	; !!!
;		IF	_SAFE_DEBUG
;		illegal
;		ENDC
		moveq	#0,d7		; !!!
RTEF_huj1				; !!!
		ENDC

		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	(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

		IF	_SAFE
		bpl.b	RTEF_huj2	; !!!
;		IF	_SAFE_DEBUG
;		illegal
;		ENDC
		moveq	#0,d7		; !!!
RTEF_huj2				; !!!
		ENDC

; 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


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

RenderEnvFace
		bsr.w	CalcRenderFaceParamsA
		bne.w	REF_End

		movea.l	_EnvMapPtr,a1

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

		move.l	#1,section

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

		tst.l	d6
		bpl.w	REF_0

		move.l	(xl,pc),d6
		move.l	(xs1,pc),d7
		bra.w	REF_1
REF_loop1
		swap	d6
		swap	d7
		sub.w	d6,d7

		IF	_SAFE
		bpl.b	REF_huj1	; !!!
;		IF	_SAFE_DEBUG
;		illegal
;		ENDC
		moveq	#0,d7		; !!!
REF_huj1				; !!!
		ENDC

		lea	(a6,d6.w),a4

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

		move.w	d0,d5		; preload register for better pairing
REF_loop0
		move.b	d1,d5
		add.l	a0,d0		; paired
		move.b	(a1,d5.w*2),(a4)+
		addx.l	d3,d1
		move.w	d0,d5

		dbra	d7,REF_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	(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
REF_1
		subq.l	#1,h1
		bpl.w	REF_loop1

		tst.l	(section,pc)
		beq.b	REF_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	REF_loop1

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

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

		IF	_SAFE
		bpl.b	REF_huj2	; !!!
;		IF	_SAFE_DEBUG
;		illegal
;		ENDC
		moveq	#0,d7		; !!!
REF_huj2				; !!!
		ENDC

; 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
REF_loop2
		move.b	d1,d5
		sub.l	a0,d0		; paired
		move.b	(a1,d5.w*2),-(a4)
		subx.l	d3,d1
		move.w	d0,d5

		dbra	d7,REF_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	(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
REF_2
		subq.l	#1,h1
		bpl.w	REF_loop3

		tst.l	(section,pc)
		beq.w	REF_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	REF_loop3


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

RenderTxtFace
		bsr.w	CalcRenderFaceParamsA
		bne.w	RTF_End

		movea.l	_TxtMapPtr,a1

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

		move.l	#1,section

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

		tst.l	d6
		bpl.w	RTF_0

		move.l	(xl,pc),d6
		move.l	(xs1,pc),d7
		bra.w	RTF_1
RTF_loop1
		swap	d6
		swap	d7
		sub.w	d6,d7

		IF	_SAFE
		bpl.b	RTF_huj1	; !!!
;		IF	_SAFE_DEBUG
;		illegal
;		ENDC
		moveq	#0,d7		; !!!
RTF_huj1				; !!!
		ENDC

		lea	(a6,d6.w),a4

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

		move.w	d0,d5		; preload register for better pairing
RTF_loop0
		move.b	d1,d5
		add.l	a0,d0		; paired
		move.b	(a1,d5.w),(a4)+
		addx.l	d3,d1
		move.w	d0,d5

		dbra	d7,RTF_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	(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
RTF_1
		subq.l	#1,h1
		bpl.w	RTF_loop1

		tst.l	(section,pc)
		beq.b	RTF_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	RTF_loop1

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

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

		IF	_SAFE
		bpl.b	RTF_huj2	; !!!
;		IF	_SAFE_DEBUG
;		illegal
;		ENDC
		moveq	#0,d7		; !!!
RTF_huj2				; !!!
		ENDC

; 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
RTF_loop2
		move.b	d1,d5
		sub.l	a0,d0		; paired
		move.b	(a1,d5.w),-(a4)
		subx.l	d3,d1
		move.w	d0,d5

		dbra	d7,RTF_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	(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
RTF_2
		subq.l	#1,h1
		bpl.w	RTF_loop3

		tst.l	(section,pc)
		beq.w	RTF_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	RTF_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

;_tmp		DC.L	0
;_dxl		DC.L	0
;_dxs1		DC.L	0
;_dxs2		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

; 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.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.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.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.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.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.l	#1,d3

; d3.l	odu (24.8)

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

; d4.l	odv (24.8)

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

; d5.l	odut (24.8)

		move.l	a6,d6
		asl.l	#8,d6
		divs.l	d0,d6
		addq.l	#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.l	#1,d3
		move.l	d3,dxl

; dxl.l	delta of longnest span (16.16)

		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.l	#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

		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.l	#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

		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.l	_ChunkyWidth,d3
		movea.l	_ChunkyAdr,a6
		lea	(a6,d3.l),a6

		move.l	(dxl,pc),d6
		sub.l	(dxs1,pc),d6
		tst.l	d0
		bne.b	CRFP_4
		move.l	(dxs2,pc),d6
		sub.l	(dxl,pc),d6
CRFP_4
;		move.l	d6,_tmp

;		move.l	(dxl,pc),_dxl
;		move.l	(dxs1,pc),_dxs1
;		move.l	(dxs2,pc),_dxs2

		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


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

RenderVClipFace
		lea	TM_tmpVertices,a3
		moveq	#-2,d7

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

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

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

		tst.w	d7
		bmi.b	rcf0

		lea	TM_tmpVertices,a3
		lea	TM_tmpcVertices,a4
		moveq	#-3,d6

rcf_Loop0	move.l	a3,a1
		lea	(a3,vt_SIZEOF),a3
		move.l	a3,a2
		bsr.w	rcf_HClipEdge

		dbra	d7,rcf_Loop0

		move.l	a3,a1
		lea	TM_tmpVertices,a2
		bsr.w	rcf_HClipEdge

		tst.w	d6
		bmi.b	rcf0

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

rcf_Loop1	move.l	a2,a0
		move.l	d2,(a0,fc_Flags)

		move.l	#rcf_ReturnHere,-(sp)
		movem.l	d0-d7/a0-a6,-(sp)
		bra.w	RenderFace2
rcf_ReturnHere
		lea	(a2,fc_SIZEOF),a2

		dbra	d6,rcf_Loop1
rcf0
		movem.l	(sp)+,d0-d7/a0-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)

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	rcf_vce4

		rts

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	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	rcf_vce10
		bset	#TOP_VCLIP_BIT,d0
		bra.w	rcf_vce1a
rcf_vce10
		cmpi.l	#CHUNKY_HEIGHT,d4
		blt.w	rcf_vce1a
		bset	#BOTTOM_VCLIP_BIT,d0
		bra.w	rcf_vce1a

rcf_vce0	btst	#RIGHT_VCLIP_BIT,d0
		beq.w	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	rcf_vce5
		bset	#TOP_VCLIP_BIT,d0
		bra.b	rcf_vce1a
rcf_vce5
		cmpi.l	#CHUNKY_HEIGHT,d4
		blt.b	rcf_vce1a
		bset	#BOTTOM_VCLIP_BIT,d0
		bra.b	rcf_vce1a

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)
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	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	rcf_vce6
		bset	#TOP_VCLIP_BIT,d0
		bra.b	rcf_vce7
rcf_vce6
		cmpi.l	#CHUNKY_HEIGHT,d4
		blt.b	rcf_vce7
		bset	#BOTTOM_VCLIP_BIT,d0
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

rcf_vce2	btst	#RIGHT_VCLIP_BIT,d0
		beq.w	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	rcf_vce8
		bset	#TOP_VCLIP_BIT,d0
		bra.b	rcf_vce9
rcf_vce8
		cmpi.l	#CHUNKY_HEIGHT,d4
		blt.b	rcf_vce9
		bset	#BOTTOM_VCLIP_BIT,d0
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

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)

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	rcf_hce4

		rts

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	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	rcf_hce1a

rcf_hce0	btst	#BOTTOM_VCLIP_BIT,d0
		beq.b	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	rcf_hce1a

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)
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	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
rcf_hce3a
		rts

rcf_hce2	btst	#BOTTOM_VCLIP_BIT,d0
		beq.w	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

rcf_hce3

; V2 not clipped

		rts

		CNOP	0,4

TM_cFaces
TM_cFace1	DC.L	TM_cVertex1,TM_cVertex2,TM_cVertex3
		DCB.B	fc_SIZEOF-3*4
TM_cFace2	DC.L	TM_cVertex1,TM_cVertex3,TM_cVertex4
		DCB.B	fc_SIZEOF-3*4
TM_cFace3	DC.L	TM_cVertex1,TM_cVertex4,TM_cVertex5
		DCB.B	fc_SIZEOF-3*4
TM_cFace4	DC.L	TM_cVertex1,TM_cVertex5,TM_cVertex6
		DCB.B	fc_SIZEOF-3*4
TM_cFace5	DC.L	TM_cVertex1,TM_cVertex6,TM_cVertex7
		DCB.B	fc_SIZEOF-3*4

EnvMap		dc.l	0

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
; a0.l	pointer to OBJECT

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

		movem.l	(a0),d0-d5

		move.l	#VALUES_NUMBER,d6
		move.l	d6,d7
		add.l	d6,d6

		mulu	d6,d3
		add.l	d7,d3
		mulu	d6,d4
		add.l	d7,d4
		mulu	d6,d5
		add.l	d7,d5

		move.l	_TM_RotateTable,a1
		lea	(a1,d5.l),a3
		lea	(a1,d4.l),a2
		adda.l	d3,a1

		move.l	(a0,obj_VNumber),d7
		subq.w	#1,d7
		move.l	(a0,obj_Vertices),a0

		move.l	_TM_PerspectiveTable,a4
		move.l	_TM_ArcSineTable,a5
		lea	(a5,128*4.w),a5

; ---------------------------------------
; d0.l	PosX
; d1.l	PosY
; d2.l	PosZ
; d3.l	FREE
; d4.l	FREE
; d5.l	FREE
; d6.l	FREE
; d7.l	vertices number (-1)
; a0.l	pointer to vertices
; a1.l	pointer to sin(RotX) lookup table
; a2.l	pointer to sin(RotY) lookup table
; a3.l	pointer to sin(RotZ) lookup table
; a4.l	pointer to perspective table
; a5.l	pointer to arcus sine table (0 value position)
; a6.l	FREE

TM_toI_Loop
		movem.l	(a0),d3-d5

; rotate around Z axis

		move.w	d3,d6
		move.w	(a3,d3.w*2,COSINE_OFFSET.l),d3
		add.w	(a3,d4.w*2),d3
		move.w	(a3,d4.w*2,COSINE_OFFSET.l),d4
		sub.w	(a3,d6.w*2),d4

; rotate around Y axis

		move.w	d3,d6
		move.w	(a2,d3.w*2,COSINE_OFFSET.l),d3
		sub.w	(a2,d5.w*2),d3
		move.w	(a2,d5.w*2,COSINE_OFFSET.l),d5
		add.w	(a2,d6.w*2),d5

; rotate around X axis

		move.w	d4,d6
		move.w	(a1,d4.w*2,COSINE_OFFSET.l),d4
		add.w	(a1,d5.w*2),d4
		move.w	(a1,d5.w*2,COSINE_OFFSET.l),d5
		sub.w	(a1,d6.w*2),d5

; translate

		ext.l	d3
		ext.l	d4
		ext.l	d5

		add.l	d0,d3
		add.l	d1,d4
		add.l	d2,d5

		move.l	d5,(a0,vt_zt)
		ble.w	TM_toI4

; perspective projection

		move.l	(a4,d5.l*4,-4.b),d6

		muls.l	d6,d3
		swap	d3
		ext.l	d3

		muls.l	d6,d4
		swap	d4
		ext.l	d4

		move.l	d3,d5
		asr.l	#2,d5
		sub.l	d3,d5
		move.l	d5,a6
		move.l	d4,d5
		asr.l	#2,d5
		sub.l	d4,d5
		move.l	d5,h1

		moveq	#0,d5

		add.l	#CHUNKY_WIDTH2,d3
		bpl.b	TM_toI0
		bset	#LEFT_VCLIP_BIT,d5
		bra.b	TM_toI1
TM_toI0
		cmpi.l	#CHUNKY_WIDTH,d3
		blt.b	TM_toI1
		bset	#RIGHT_VCLIP_BIT,d5
TM_toI1
		add.l	#CHUNKY_HEIGHT2,d4
		bpl.b	TM_toI2
		bset	#TOP_VCLIP_BIT,d5
		bra.b	TM_toI3
TM_toI2
		cmpi.l	#CHUNKY_HEIGHT,d4
		blt.b	TM_toI3
		bset	#BOTTOM_VCLIP_BIT,d5
TM_toI3
		move.l	d3,(a0,vt_xp)
		move.l	d4,(a0,vt_yp)
		move.l	d5,(a0,vt_ClipBits)

; translate vertices normals (for environment mapping)

		tst.l	EnvMap
		bne.b	TM_toI4

		movem.l	(a0,vt_xn),d3-d5

; rotate around Z axis

		move.w	d3,d6
		move.w	(a3,d3.w*2,COSINE_OFFSET.l),d3
		add.w	(a3,d4.w*2),d3
		move.w	(a3,d4.w*2,COSINE_OFFSET.l),d4
		sub.w	(a3,d6.w*2),d4

; rotate around Y axis

		move.w	d3,d6
		move.w	(a2,d3.w*2,COSINE_OFFSET.l),d3
		sub.w	(a2,d5.w*2),d3
		move.w	(a2,d5.w*2,COSINE_OFFSET.l),d5
		add.w	(a2,d6.w*2),d5

; rotate around X axis

		move.w	d4,d6
		move.w	(a1,d4.w*2,COSINE_OFFSET.l),d4
		add.w	(a1,d5.w*2),d4

		move.l	(a5,d3.w*4),d5
		sub.l	a6,d5
		move.l	d5,(a0,vt_u)
		move.l	(a5,d4.w*4),d5
		sub.l	(pc,h1),d5
		move.l	d5,(a0,vt_v)

;		neg.l	d3
;		sub.l	a6,d3
;		add.l	#128,d3
;		move.l	d3,(a0,vt_u)
;		neg.l	d4
;		sub.l	(pc,h1),d4
;		add.l	#128,d4
;		move.l	d4,(a0,vt_v)

TM_toI4
		lea	(a0,vt_SIZEOF),a0

		dbra	d7,TM_toI_Loop

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


; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
; a0.l	pointer to OBJECT

_TM_TransformObjectII
		move.l	#1,EnvMap
		bsr.w	_TM_TransformObjectI
		move.l	#0,EnvMap
		rts

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
; a0.l	pointer to SCENE
; a1.l	pointer to DepthBuffer
; return visible faces number

_TM_CreateDepthBuffer
		movem.l	d2-d7/a0-a6,-(sp)

		moveq	#0,d0

		move.l	(a0,sc_ONumber),d1
		subq.w	#1,d1
		move.l	(a0,sc_Objects),a0
TM_cdb_Loop2
		btst.b	#OB_DISPLAY,(a0,obj_Flags+3)
		beq.w	TM_cdb5

		btst.b	#OB_NOBACKFACE,(a0,obj_Flags+3)
		bne.w	TM_cdb6

		move.l	(a0,obj_FNumber),d7
		subq.w	#1,d7
		move.l	(a0,obj_Faces),a5
TM_cdb_Loop1
		move.l	(a5,fc_V1),a2
		move.l	(a2,vt_zt),d2
		ble.b	TM_cdb0
		move.l	(a5,fc_V2),a3
		move.l	(a3,vt_zt),d3
		ble.b	TM_cdb0
		move.l	(a5,fc_V3),a4
		move.l	(a4,vt_zt),d4
		ble.b	TM_cdb0

		add.l	d3,d2
		add.l	d4,d2
		move.l	d2,(a5,fc_AvgZ)

; a2.l	pointer to V1
; a3.l	pointer to V2
; a4.l	pointer to V3

		move.l	(a2,vt_ClipBits),d2
		bne.b	TM_cdb1
		move.l	(a3,vt_ClipBits),d3
		bne.b	TM_cdb2
		move.l	(a4,vt_ClipBits),d4
		bne.b	TM_cdb3

		bclr.b	#FB_VCLIP-8,(a5,fc_Flags+2)
TM_cdb4

;	backface culling

		move.l	(a3,vt_xp),d2
		move.l	(a2,vt_xp),d3
		sub.l	d2,d3
		move.l	(a4,vt_xp),d4
		sub.l	d2,d4
		move.l	(a3,vt_yp),d2
		move.l	(a4,vt_yp),d5
		sub.l	d2,d5
		move.l	(a2,vt_yp),d6
		sub.l	d2,d6
		muls	d5,d3
		muls	d6,d4
		cmp.l	d4,d3
		bge.b	TM_cdb0

		move.l	a5,(a1)+
		addq.l	#1,d0
TM_cdb0
		lea	(a5,fc_SIZEOF),a5

		dbra	d7,TM_cdb_Loop1
TM_cdb5
		lea	(a0,obj_SIZEOF),a0

		dbra	d1,TM_cdb_Loop2

		move.l	#0,(a1)

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

TM_cdb1
		move.l	(a3,vt_ClipBits),d3
TM_cdb2
		move.l	(a4,vt_ClipBits),d4
TM_cdb3
		and.l	d3,d2
		and.l	d4,d2
		bne.b	TM_cdb0
		bset.b	#FB_VCLIP-8,(a5,fc_Flags+2)
		bra.b	TM_cdb4

TM_cdb6
		move.l	(a0,obj_FNumber),d7
		subq.w	#1,d7
		move.l	(a0,obj_Faces),a5
TM_cdb_Loop3
		move.l	(a5,fc_V1),a2
		move.l	(a2,vt_zt),d2
		ble.b	TM_cdb7
		move.l	(a5,fc_V2),a3
		move.l	(a3,vt_zt),d3
		ble.b	TM_cdb7
		move.l	(a5,fc_V3),a4
		move.l	(a4,vt_zt),d4
		ble.b	TM_cdb7

		add.l	d3,d2
		add.l	d4,d2
		move.l	d2,(a5,fc_AvgZ)

; a2.l	pointer to V1
; a3.l	pointer to V2
; a4.l	pointer to V3

		move.l	(a2,vt_ClipBits),d2
		bne.b	TM_cdb8
		move.l	(a3,vt_ClipBits),d3
		bne.b	TM_cdb9
		move.l	(a4,vt_ClipBits),d4
		bne.b	TM_cdb10

		bclr.b	#FB_VCLIP-8,(a5,fc_Flags+2)
TM_cdb11
		move.l	a5,(a1)+
		addq.l	#1,d0
TM_cdb7
		lea	(a5,fc_SIZEOF),a5
TM_cdb12
		dbra	d7,TM_cdb_Loop3

		bra.w	TM_cdb5

TM_cdb8
		move.l	(a3,vt_ClipBits),d3
TM_cdb9
		move.l	(a4,vt_ClipBits),d4
TM_cdb10
		and.l	d3,d2
		and.l	d4,d2
		bne.b	TM_cdb7
		bset.b	#FB_VCLIP-8,(a5,fc_Flags+2)
		bra.b	TM_cdb11


; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
; d0.w	number of faces
; a0.l	pointer to DepthBuffer

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

		move.w	d0,d1
		bra.b	TM_sdb0
TM_sdb_Loop0
		move.w	d1,d2
TM_sdb_Loop1
		move.w	d2,d3
		sub.w	d1,d3
		move.w	d2,d4
TM_sdb_Loop2
		move.l	([a0,d3.w*4],fc_AvgZ.w),d5
		cmp.l	([a0,d4.w*4],fc_AvgZ.w),d5
		bge.b	TM_sdb1

		move.l	(a0,d3.w*4),d5
		move.l	(a0,d4.w*4),(a0,d3.w*4)
		move.l	d5,(a0,d4.w*4)

		sub.w	d1,d4
		sub.w	d1,d3
		bpl.b	TM_sdb_Loop2
TM_sdb1
		addq.w	#1,d2
		cmp.w	d0,d2
		blt.b	TM_sdb_Loop1
TM_sdb0
		lsr.w	#1,d1
		bne.b	TM_sdb_Loop0

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


                SECTION vert,bss
TM_tmpVertices	DCB.B	7*vt_SIZEOF

TM_tmpcVertices
TM_cVertex1	DCB.B	vt_SIZEOF
TM_cVertex2	DCB.B	vt_SIZEOF
TM_cVertex3	DCB.B	vt_SIZEOF
TM_cVertex4	DCB.B	vt_SIZEOF
TM_cVertex5	DCB.B	vt_SIZEOF
TM_cVertex6	DCB.B	vt_SIZEOF
TM_cVertex7	DCB.B	vt_SIZEOF

		END

; ллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллллл
