		include	..\spec_psx\tomb.inc

mvmva	MACRO	sf,mx,v,cv,lm
	dw	$4a400012|((sf&3)<<19)|((mx&3)<<17)|((v&3)<<15)|((cv&3)<<13)|((lm&3)<<11)
	ENDM

		global	S_InsertRoom
		global	dude_insert_room
		global	dude_clip3
		global	dude_clip4
		global	dude_subdivide_gt4_
		global	dude_subdivide_gt4
		global	dude_subdivide_gt3_
		global	dude_subdivide_gt3
		global	dude_wibble
		global	dude_insert_mesh_clipped
		global	dude_insert_mesh_quads
		global	dude_insert_mesh_tris
		global	dude_subdivide_mesh_GT4

		xref	phd_left
		xref	phd_right
		xref	phd_top
		xref	phd_bottom
		xref	water_effect
		xref	shade_effect
		xref	underwater_table
		xref	wibble_offset
		xref	psxtextinfo
		xref	dude_envmap_tpage
		xref	GdwUWClutSub

		xref	DownLoadMatrix

		xref	db

JAP		equ		0

				rsreset
vtx_xy			rb		0
vtx_x			rh		1
vtx_y			rh		1
vtx_zg			rb		0
vtx_z			rh		1
vtx_g			rh		1
vtx_uv			rb		0
vtx_u			rb		1
vtx_v			rb		1
vtx_p			rh		1
vtx_rgb			rw		1
vtx_size		rb		0

				rsreset
s0_stash		rw		1
s1_stash		rw		1
s2_stash		rw		1
s3_stash		rw		1
s4_stash		rw		1
s5_stash		rw		1
s6_stash		rw		1
s7_stash		rw		1
gp_stash		rw		1
s8_stash		rw		1
ra_stash		rw		1
otz_stash		rw		1

wibble_index	rw		1
polybuf_limit	rw		1
clip_a0_stash	rw		1
clip_a1_stash	rw		1

clip_left	 	rw		1
clip_right		rw		1
clip_top		rw		1
clip_bottom		rw		1

cxy0_stash		rw		1
cxy1_stash		rw		1
cxy2_stash		rw		1
cxy3_stash		rw		1

ra_stash2		rw		1
envmap_tpage	rw		1
clut_sub		rw		1
unused_stash	rw		1

vertex0			rb		vtx_size
vertex1			rb		vtx_size
vertex2			rb		vtx_size
vertex3			rb		vtx_size
ins_room_scsize rb		0

scratch equr	v0		; current scratch pad addr, usually $1f800000 but moves up for subdiv
temp	equr	v1		; general temp.  shared with num, otz, cl_jout
objptr	equr	a0		; current mesh data ptr
txtbase equr	a1		; addr of psx texture structs (uv's, clut, tpage, 3/4 codes, windowed flag for each texture)
otbase	equr	a2		; addr of ot
polyptr equr	a3		; current prim pointer
cxy0	equr	t0		; screen xy values & temps
cxy1	equr	t1
cxy2	equr	t2
cxy3	equr	t3
vz0 	equr	t4		; screen z values & temps
vz1 	equr	t5
vz2 	equr	t6
vz3 	equr	t7
vtx0	equr	s0		; world values & temps
vtx1	equr	s1
vtx2	equr	s2
vtx3	equr	s3
pblimit	equr	s4		; limit of current prim buffer.
sdflag	equr	s5		; general subdiv flag.  if &4, keep trying to nclip.  if &3, forced subdiv level.  (objects only) if &8, mid sort
dqflag	equr	s6		; (rooms only) draw to depthq frig flag: if !0, always draw polys past DPQ_END (at DPQ_END)
roomtxy	equr	s7		; x/y extra room translate
vbase	equr	t8		; base of room or object vertices
objend	equr	t9		; end of current mesh data, or count
roomtz	equr	gp
objptr2	equr	s8		; (rooms only) ptr to gt4 texture numbers (stored separately from vertex numbers)
temp_ra	equr	ra

num 	equr	v1		; number of vertices/polys (very temp)
otz		equr	v1		; calculated pos in OT
sdlimit	equr	s6		; (objects only) subdivision limit. if <0, no subdiv. 0=1 level, 1=2 level.
nbase	equr	s8		; (objects only) base of object normals, if present.

norm0	equr	t4		; (objects only) vertex normal pointers for envmapping
norm1	equr	t5
norm2	equr	t6
norm3	equr	t7

; clipping
cl_xy0	equr	t0		; xy coords
cl_xy1	equr	t1
cl_xy2	equr	t2
cl_xy3	equr	t3
cl_tx0	equr	s0		; temp values
cl_tx1	equr	s1
cl_tx2	equr	s2
cl_tx3	equr	s3
cl_jout	equr	v1		; where to jump to if clip fails

; gt4 subdivide
sd_gt4_pv0		equr	t0
sd_gt4_pv1		equr	t1
sd_gt4_pv2		equr	t2
sd_gt4_pv3		equr	t3
sd_gt4_clut		equr	t4
sd_gt4_tpage	equr	t5
sd_gt4_code		equr	t6
sd_gt4_level	equr	t7
sd_gt4_temp0	equr	s0
sd_gt4_temp1	equr	s1
sd_gt4_temp2	equr	s2
sd_gt4_temp3	equr	s3

; gt3 subdivide
sd_gt3_pv0		equr	t0
sd_gt3_pv1		equr	t1
sd_gt3_pv2		equr	t2
sd_gt3_clut		equr	t4
sd_gt3_tpage	equr	t5
sd_gt3_code		equr	t6
sd_gt3_level	equr	t7
sd_gt3_temp0	equr	s0
sd_gt3_temp1	equr	s1
sd_gt3_temp2	equr	s2
sd_gt3_temp3	equr	s3

; underwater wibble
wib_idx	equr	s0		; current wibble index
wib_pvx	equr	s1		; pointer to scratchpad vertex
wib_pvn	equr	s2		; pointer to vertex number mesh info
wib_tmp	equr	s3		; wibble temp


	if 0
		db		'Dude greets: Shroomz, Bag, The Menzie, Nagra, K-Comm, Snake & McBain of EZ-o-Ray... '
		db		'Mail me at ataru@dial.pipex.com',0
		cnop	0,4

S_InsertRoom
		gpr.lw	t3,water_effect
		move	t5,ra
		jal		DownLoadMatrix
		move	t4,a1
		gpr.lw	a1,psxtextinfo
		move	ra,t5
		bz		t3,dude_insert_room
		clr		t0
		gpr.lw	t0,GdwUWClutSub

dude_insert_room
		lui 	scratch,$1f80
		sc.sw	s0,s0_stash
		sc.sw	s1,s1_stash
		sc.sw	s2,s2_stash
		sc.sw	s3,s3_stash
		sc.sw	s4,s4_stash
		sc.sw	s5,s5_stash
		sc.sw	s6,s6_stash
		sc.sw	s7,s7_stash
		sc.sw	gp,gp_stash
		sc.sw	s8,s8_stash
		sc.sw	ra,ra_stash
		sc.sw	t0,clut_sub
		move	roomtxy,a2
		gpr.lw	a2,db+db_ot
		move	at,a3
		gpr.lw	a3,db+db_polyptr
		addiu	otbase,ROOM_OT_BIAS<<2
		gpr.lh	t0,phd_left
		addiu	vbase,objptr,4
		gpr.lh	t1,phd_right
		sll 	t0,16
		gpr.lh	t2,phd_top
		sll 	t1,16
		gpr.lh	t3,phd_bottom
		sll 	t2,16
		gpr.lw	t5,shade_effect
		inc 	t3
		sc.sw	t5,wibble_index
		lhu 	num,2(objptr)
		sll 	t3,16
		sc.sw	t0,clip_left
		sc.sw	t1,clip_right
		sc.sw	t2,clip_top
		sc.sw	t3,clip_bottom
		sll 	num,2
		gpr.lw	pblimit,db+db_polybuf_limit
		move	dqflag,t4
		addu	objptr,vbase,num
		move	roomtz,at						; this decks gp!!!

		lhu 	num,(objptr)
		addiu	objptr2,objptr,2
		sll		num,1
		addu	objptr,objptr2,num
		andi	at,objptr,2
		bz		num,.doGT3s
		addu	objptr,at
		sll		num,2
		addu	objend,objptr,num

.GT4lp	cmpu	polyptr,pblimit
		bhs		.exit
		li		sdflag,0
		lw		vtx1,(objptr)
		addiu	objptr,8
		lw		vtx3,4-8(objptr)
		andi	vtx0,vtx1,$ffff
		srl		vtx1,16
		andi	vtx2,vtx3,$ffff
		addu	vtx0,vbase
		lw		vtx0,(vtx0)
		srl		vtx3,16

		andi	at,vtx0,$03e0
		sll		at,19
		andi	temp,vtx0,$7c00
		or		temp,at
		addu	temp,roomtxy
		mtc2	temp,C2_VXY0			; xy0
		andi	vz0,vtx0,$001f
		sll		vz0,10
		addu	vz0,roomtz
		mtc2	vz0,C2_VZ0				; z0

		sc.sw	temp,vertex0+vtx_xy		; save for later, if subdiv needed
		lhu		temp,(objptr2)

		gte_rtps

		jal		dude_unpack3
		sc.sw	vtx0,vertex0+vtx_zg		; convert packed xyz data back to room coordinates

		mfc2	cl_xy0,C2_SXY2
		cfc2	at,C2_FLAG
		sll		temp,4

		gte_rtpt						; 22 cycles...
		sc.sw	vtx1,vertex1+vtx_zg
		sc.sw	vtx2,vertex2+vtx_zg
		sc.sw	vtx3,vertex3+vtx_zg
		sc.sh	vz0,vertex0+vtx_z
		sc.sh	vz1,vertex1+vtx_z
		sc.sh	vz2,vertex2+vtx_z
		sc.sh	vz3,vertex3+vtx_z
		addu	temp,txtbase
		lw		cxy1,(temp)
		lw		cxy2,4(temp)
		lw		cxy3,8(temp)
		lw		temp,12(temp)
		cfc2	vz0,C2_FLAG
		sc.lw	vz1,clut_sub
		or		at,vz0
		bpl		.norml4
		subu	cxy1,vz1				; modify clut for underwater...

		mfc2	vz0,C2_SZ0
		mfc2	vz1,C2_SZ1
		mfc2	vz2,C2_SZ2
		mfc2	vz3,C2_SZ3
		or		vz0,vz1
		or		vz0,vz2
		or		vz0,vz3
		srl		vz0,7
		bz		vz0,.next4
		nop
		b		.shady4
		li		sdflag,2+4

.norml4	gte_nclip
		mfc2	at,C2_MAC0				; read nclip
		nop
		bpl 	.next4					; skip if poly is backfacing
		nop

.shady4	sc.sw	cxy1,vertex0+vtx_uv
		sc.sw	cxy2,vertex1+vtx_uv
		sc.sw	cxy3,vertex2+vtx_uv
		sc.sw	temp,vertex3+vtx_uv

		jal		dude_clip4
		pcr.la	cl_jout,.next4

		mfc2	vz0,C2_SZ0
		mfc2	vz1,C2_SZ1
		mfc2	vz2,C2_SZ2
		mfc2	vz3,C2_SZ3

		cmp		vz0,vz1
		bhs 	.z41
		move	otz,vz0
		move	otz,vz1
.z41	cmp 	otz,vz2
		bhs 	.z42
		nop
		move	otz,vz2
.z42	cmp		otz,vz3
		bhs		.z43
		sc.lw	wib_idx,wibble_index
		move	otz,vz3
.z43
		cmpi	otz,DPQ_END+1
		blo		.dow4
		nop
		bz		dqflag,.next4
		li		otz,DPQ_END

.dow4	addiu	wib_pvx,scratch,vertex0
		bltzal	wib_idx,dude_wibble
		addiu	wib_pvn,objptr,-4*2

		cmpi	otz,SUBDIVIDE_Z
		bhs 	.nosd4

		sc.sw	cxy0,cxy0_stash
		sc.sw	cxy1,cxy1_stash
		sc.sw	cxy2,cxy2_stash
		sc.sw	cxy3,cxy3_stash

		addiu	sd_gt4_pv0,scratch,vertex0
		lbu		vtx0,vtx_g(sd_gt4_pv0)
		addiu	sd_gt4_pv1,scratch,vertex1
		lbu		vtx1,vtx_g(sd_gt4_pv1)
		addiu	sd_gt4_pv2,scratch,vertex2
		lbu		vtx2,vtx_g(sd_gt4_pv2)
		addiu	sd_gt4_pv3,scratch,vertex3
		lbu		vtx3,vtx_g(sd_gt4_pv3)

		jal		dude_rgb4
		sc.sw	otz,otz_stash

		sw		vtx0,vtx_rgb(sd_gt4_pv0)
		sw		vtx1,vtx_rgb(sd_gt4_pv1)
		sw		vtx2,vtx_rgb(sd_gt4_pv2)
		sw		vtx3,vtx_rgb(sd_gt4_pv3)

		swc2	C2_VXY0,vtx_xy(sd_gt4_pv1)
		swc2	C2_VXY1,vtx_xy(sd_gt4_pv2)
		swc2	C2_VXY2,vtx_xy(sd_gt4_pv3)

		sc.lhu	sd_gt4_clut,vertex0+vtx_p
		bz		sdflag,.l1
		slti	sd_gt4_level,otz,SUBDIVIDE_Z2
		andi	sd_gt4_level,sdflag,3
.l1		sc.lhu 	sd_gt4_tpage,vertex1+vtx_p
		sll		sd_gt4_clut,16
		sc.lbu	sd_gt4_code,vertex2+vtx_p+0
		sll		sd_gt4_tpage,16
		sll		sd_gt4_code,24
		jal 	dude_subdivide_gt4
		addiu	scratch,ins_room_scsize

		subiu	scratch,ins_room_scsize
		sc.lw	otz,otz_stash
		bnz		sdflag,.next4							; dont do old poly if it limited
		cmpi	otz,NEAR_CLIP						; decide if the old poly should be drawn
		blo 	.next4
		sc.lbu	vz0,vertex3+vtx_p+0					; restore stuff after subdiv.
		addiu	otz,WALL_L							; handy frig to bias special frig polys' z values
		bnz 	vz0,.next4

		sc.lw	cxy0,cxy0_stash
		clr		vz0
		sc.lw	cxy1,cxy1_stash
		clr		vz1
		sc.lw	cxy2,cxy2_stash
		clr		vz2
		sc.lw	cxy3,cxy3_stash
		clr		vz3

.nosd4	sc.lbu	vtx0,vertex0+vtx_g
		subiu	vz0,DPQ_START
		sc.lbu	vtx1,vertex1+vtx_g
		subiu	vz1,DPQ_START
		sc.lbu	vtx2,vertex2+vtx_g
		subiu	vz2,DPQ_START
		sc.lbu	vtx3,vertex3+vtx_g
		subiu	vz3,DPQ_START

		sw		cxy0,xy0(polyptr)
		sw		cxy1,xy1(polyptr)
		sw		cxy2,xy2(polyptr)
		sw		cxy3,xy3(polyptr)

		blez	vz0,.ddq40
		srl 	vz0,SHADE_SHIFT
		subu	vtx0,vz0
		bgez	vtx0,.ddq40
		nop
		clr		vtx0
.ddq40	sc.lw	cxy0,vertex0+vtx_uv
		blez	vz1,.ddq41
		srl 	vz1,SHADE_SHIFT
		subu	vtx1,vz1
		bgez	vtx1,.ddq41
		nop
		clr		vtx1
.ddq41	sc.lw	cxy1,vertex1+vtx_uv
		blez	vz2,.ddq42
		srl 	vz2,SHADE_SHIFT
		subu	vtx2,vz2
		bgez	vtx2,.ddq42
		nop
		clr		vtx2
.ddq42	sc.lhu	cxy2,vertex2+vtx_uv
		blez	vz3,.ddq43
		srl 	vz3,SHADE_SHIFT
		subu	vtx3,vz3
		bgez	vtx3,.ddq43
		nop
		clr		vtx3
.ddq43	jal		dude_rgb4
		sc.lhu	cxy3,vertex3+vtx_uv

		cmpiu	otz,MIPMAP_START
		blo		.nomip4
		sc.lbu	vz2,vertex2+vtx_p+0
		andi	vz0,cxy0,$ffff
		andi	vz1,cxy1,$ffff
		xor		cxy0,vz0
		xor		cxy1,vz1
		srl		vz0,1
		ori		vz0,$8080
		srl		vz1,1
		ori		vz1,$8080
		srl		cxy2,1
		ori		cxy2,$8080
		srl		cxy3,1
		ori		cxy3,$8080
		or		cxy0,vz0
		or		cxy1,vz1

.nomip4	sw		cxy0,uv0clut(polyptr)
		sw		cxy1,uv1tpg(polyptr)
		sw		cxy2,uv2(polyptr)
		sw		cxy3,uv3(polyptr)
		sll		vz2,24
		or		vtx0,vz2
		sw		vtx0,rgb0c(polyptr)
		sw		vtx1,rgb1(polyptr)
		sw		vtx2,rgb2(polyptr)
		sw		vtx3,rgb3(polyptr)
		srl 	otz,OTRIGHT+2
		sll 	otz,2
		addu	otz,otbase
		lw		vz0,(otz)
		li		at,$0c000000
		or		vz0,at
		sw		vz0,(polyptr)
		sw		polyptr,(otz)
		addiu	polyptr,gt4_sz

.next4	bne 	objptr,objend,.GT4lp
		addiu	objptr2,2

.doGT3s	lhu 	num,(objptr)
		inc.h	objptr
		andi	at,objptr,2
		bz		num,.exit
		addu	objptr,at
		sll 	objend,num,3
		addu	objend,objptr

.GT3lp	cmpu	polyptr,pblimit
		bhs		.exit
		li		sdflag,0
		lw		vtx1,(objptr)
		addiu	objptr,8
		lw		vtx3,4-8(objptr)

		andi	vtx0,vtx1,$ffff
		srl		vtx1,16
		andi	vtx2,vtx3,$ffff
		jal		dude_unpack3
		srl		vtx3,16

		gte_rtpt						; 22 cycles...
		sc.sw	vtx1,vertex0+vtx_zg
		sc.sw	vtx2,vertex1+vtx_zg
		sc.sw	vtx3,vertex2+vtx_zg
		sc.sh	vz1,vertex0+vtx_z
		sc.sh	vz2,vertex1+vtx_z
		sc.sh	vz3,vertex2+vtx_z
		sll		vtx0,4
		addu	vtx0,txtbase
		lw		vtx1,4(vtx0)
		lw		vtx2,8(vtx0)
		lw		vtx3,12(vtx0)
		lw		vtx0,(vtx0)
		cfc2	vz0,C2_FLAG
		sc.lw	temp,clut_sub
		bpl		.norml3
		subu	vtx0,temp				; modify clut for underwater...

		mfc2	vz0,C2_SZ1
		mfc2	vz1,C2_SZ2
		mfc2	vz2,C2_SZ3
		or		vz0,vz1
		or		vz0,vz2
		bz		vz0,.next3
		nop
		b		.shady3
		li		sdflag,2+4

.norml3	gte_nclip
		mfc2	at,C2_MAC0
		nop
		bmi		.next3
		nop

.shady3	sc.sw	vtx0,vertex0+vtx_uv
		sc.sw	vtx1,vertex1+vtx_uv
		sc.sw	vtx2,vertex2+vtx_uv
		sc.sw	vtx3,vertex3+vtx_uv		; for windowed flag

		jal		dude_clip3
		pcr.la	cl_jout,.next3

		mfc2	vz0,C2_SZ1
		mfc2	vz1,C2_SZ2
		mfc2	vz2,C2_SZ3

		cmp		vz0,vz1
		bhs		.z31
		move	otz,vz0
		move	otz,vz1
.z31	cmp		otz,vz2
		bhs		.z32
		sc.lw	wib_idx,wibble_index
		move	otz,vz2
.z32
		cmpi	otz,DPQ_END+1
		blo		.dow3
		nop
		bz		dqflag,.next3
		li		otz,DPQ_END

.dow3	addiu	wib_pvx,scratch,vertex0
		bltzal	wib_idx,dude_wibble
		addiu	wib_pvn,objptr,-3*2

		cmpi	otz,SUBDIVIDE_Z
		bhs 	.nosd3

		sc.sw	cxy1,cxy1_stash
		sc.sw	cxy2,cxy2_stash
		sc.sw	cxy3,cxy3_stash

		addiu	sd_gt4_pv0,scratch,vertex0
		lbu		vtx0,vtx_g(sd_gt4_pv0)
		addiu	sd_gt4_pv1,scratch,vertex1
		lbu		vtx1,vtx_g(sd_gt4_pv1)
		addiu	sd_gt4_pv2,scratch,vertex2
		lbu		vtx2,vtx_g(sd_gt4_pv2)

		jal		dude_rgb3
		sc.sw	otz,otz_stash

		sw		vtx0,vtx_rgb(sd_gt4_pv0)
		sw		vtx1,vtx_rgb(sd_gt4_pv1)
		sw		vtx2,vtx_rgb(sd_gt4_pv2)

		sc.swc2	C2_VXY0,vertex0+vtx_xy
		sc.swc2	C2_VXY1,vertex1+vtx_xy
		sc.swc2	C2_VXY2,vertex2+vtx_xy

		sc.lhu	sd_gt3_clut,vertex0+vtx_p
		bz		sdflag,.l2
		slti	sd_gt3_level,otz,SUBDIVIDE_Z2
		andi	sd_gt3_level,sdflag,3
.l2		sc.lhu 	sd_gt3_tpage,vertex1+vtx_p
		sll		sd_gt3_clut,16
		sc.lbu	sd_gt3_code,vertex2+vtx_p+1
		sll		sd_gt3_tpage,16
		sll		sd_gt3_code,24
		jal		dude_subdivide_gt3
		addiu	scratch,ins_room_scsize

		subiu	scratch,ins_room_scsize
		sc.lw	otz,otz_stash
		bnz		sdflag,.next3							; dont do old poly if it limited
		cmpi	otz,NEAR_CLIP
		blo		.next3
		sc.lbu	vz0,vertex3+vtx_p+0
		addiu	otz,WALL_L
		bnz		vz0,.next3

		sc.lw	cxy1,cxy1_stash
		clr		vz0
		sc.lw	cxy2,cxy2_stash
		clr		vz1
		sc.lw	cxy3,cxy3_stash
		clr		vz2

.nosd3	sc.lbu	vtx0,vertex0+vtx_g
		subiu	vz0,DPQ_START
		sc.lbu	vtx1,vertex1+vtx_g
		subiu	vz1,DPQ_START
		sc.lbu	vtx2,vertex2+vtx_g
		subiu	vz2,DPQ_START

		sw		cxy1,xy0(polyptr)
		sw		cxy2,xy1(polyptr)
		sw		cxy3,xy2(polyptr)

		blez	vz0,.ddq30
		srl		vz0,SHADE_SHIFT
		subu	vtx0,vz0
		bgez	vtx0,.ddq30
		nop
		clr		vtx0
.ddq30	sc.lw	cxy0,vertex0+vtx_uv
		blez	vz1,.ddq31
		srl		vz1,SHADE_SHIFT
		subu	vtx1,vz1
		bgez	vtx1,.ddq31
		nop
		clr		vtx1
.ddq31	sc.lw	cxy1,vertex1+vtx_uv
		blez	vz2,.ddq32
		srl		vz2,SHADE_SHIFT
		subu	vtx2,vz2
		bgez	vtx2,.ddq32
		nop
		clr		vtx2
.ddq32	jal		dude_rgb3
		sc.lhu	cxy2,vertex2+vtx_uv

		cmpiu	otz,MIPMAP_START
		blo		.nomip3
		sc.lbu	vz2,vertex2+vtx_p+1
		andi	vz0,cxy0,$ffff
		andi	vz1,cxy1,$ffff
		xor		cxy0,vz0
		xor		cxy1,vz1
		srl		vz0,1
		ori		vz0,$8080
		srl		vz1,1
		ori		vz1,$8080
		srl		cxy2,1
		ori		cxy2,$8080
		or		cxy0,vz0
		or		cxy1,vz1

.nomip3	sw		cxy0,uv0clut(polyptr)
		sw		cxy1,uv1tpg(polyptr)
		sw		cxy2,uv2(polyptr)
		sll		vz2,24
		or		vtx0,vz2
		sw		vtx0,rgb0c(polyptr)
		sw		vtx1,rgb1(polyptr)
		sw		vtx2,rgb2(polyptr)
		srl 	otz,OTRIGHT+2
		sll 	otz,2
		addu	otz,otbase
		lw		vz0,(otz)
		li		at,$09000000
		or		vz0,at
		sw		vz0,(polyptr)
		sw		polyptr,(otz)
		addiu	polyptr,gt3_sz

.next3	bne 	objptr,objend,.GT3lp
		nop

.exit	sc.lw	s0,s0_stash
		sc.lw	s1,s1_stash
		sc.lw	s2,s2_stash
		sc.lw	s3,s3_stash
		sc.lw	s4,s4_stash
		sc.lw	s5,s5_stash
		sc.lw	s6,s6_stash
		sc.lw	s7,s7_stash
		sc.lw	gp,gp_stash
		sc.lw	ra,ra_stash
		sc.lw	s8,s8_stash
		ret
		gpr.sw	polyptr,db+db_polyptr

dude_unpack3
		addu	vtx1,vbase
		lw		vtx1,(vtx1)
		addu	vtx2,vbase
		lw		vtx2,(vtx2)
		addu	vtx3,vbase
		lw		vtx3,(vtx3)

		andi	at,vtx2,$03e0
		sll		at,19
		andi	vz2,vtx2,$7c00
		or		at,vz2
		addu	at,roomtxy
		mtc2	at,C2_VXY1				; xy2
		andi	vz2,vtx2,$001f
		sll		vz2,10
		addu	vz2,roomtz
		mtc2	vz2,C2_VZ1				; z2

		andi	at,vtx3,$03e0
		sll		at,19
		andi	vz3,vtx3,$7c00
		or		at,vz3					; at=xy3
		addu	at,roomtxy
		mtc2	at,C2_VXY2
		andi	vz3,vtx3,$001f
		sll		vz3,10					; temp=z3
		addu	vz3,roomtz
		mtc2	vz3,C2_VZ2

		andi	at,vtx1,$03e0
		sll		at,19
		andi	vz1,vtx1,$7c00
		or		at,vz1
		addu	at,roomtxy
		mtc2	at,C2_VXY0				; xy1
		andi	vz1,vtx1,$001f
		sll		vz1,10
		addu	vz1,roomtz
		mtc2	vz1,C2_VZ0				; z1
		ret
		nop

	endif
dude_clip3
		mfc2	cl_xy0,C2_SXY0			;frig so I don't need a 3 vertex clipper
dude_clip4
		sc.sw	a0,clip_a0_stash
		sc.sw	a1,clip_a1_stash
		lui		at,$1f80
		lw		cl_tx0,clip_top(at)
		mfc2	cl_xy1,C2_SXY0
		lw		cl_tx1,clip_bottom(at)
		mfc2	cl_xy2,C2_SXY1
		lw		a0,clip_left(at)
		mfc2	cl_xy3,C2_SXY2
		lw		a1,clip_right(at)
		cmp		cl_xy0,cl_tx0
		bhs		.yok4t
		cmp		cl_xy1,cl_tx0
		bhs		.yok4t
		cmp		cl_xy2,cl_tx0
		bhs		.yok4t
		cmp		cl_xy3,cl_tx0
		blo		.out
.yok4t	cmp		cl_xy0,cl_tx1
		blo		.yok4b
		cmp		cl_xy1,cl_tx1
		blo		.yok4b
		cmp		cl_xy2,cl_tx1
		blo		.yok4b
		cmp		cl_xy3,cl_tx1
		bhs		.out
.yok4b	sll		cl_tx0,cl_xy0,16
		sll		cl_tx1,cl_xy1,16
		sll		cl_tx2,cl_xy2,16
		sll		cl_tx3,cl_xy3,16
		cmp		cl_tx0,a0
		bhs		.xok4l
		cmp		cl_tx1,a0
		bhs		.xok4l
		cmp		cl_tx2,a0
		bhs		.xok4l
		cmp		cl_tx3,a0
		blo		.out
.xok4l	cmp		cl_tx0,a1
		blo		.xok4r
		cmp		cl_tx1,a1
		blo		.xok4r
		cmp		cl_tx2,a1
		blo		.xok4r
		cmp		cl_tx3,a1
		bhs		.out2
		sc.lw	a0,clip_a0_stash
.xok4r	move	cl_jout,ra
.out	sc.lw	a0,clip_a0_stash
.out2	jr		cl_jout
		sc.lw	a1,clip_a1_stash


dude_rgb4
		sll		at,vtx3,8
		or		vtx3,at
		sll		at,8
		or		vtx3,at
dude_rgb3
		sll		at,vtx0,8
		or		vtx0,at
		sll		at,8
		or		vtx0,at
		sll		at,vtx1,8
		or		vtx1,at
		sll		at,8
		or		vtx1,at
		sll		at,vtx2,8
		or		vtx2,at
		sll		at,8
		ret
		or		vtx2,at

				rsreset
sd_gt4_sc_ra	rw		1
sd_gt4_sc_pv1	rw		1
sd_gt4_sc_pv2	rw		1
sd_gt4_sc_pv3	rw		1
sd_gt4_sc_v4	rb		vtx_size
sd_gt4_sc_v5	rb		vtx_size
sd_gt4_sc_v6	rb		vtx_size
sd_gt4_sc_v7	rb		vtx_size
sd_gt4_sc_v8	rb		vtx_size
sd_gt4_sc_size	rb		0

dude_subdivide_gt4_
		dec		sd_gt4_level
		bltz	sd_gt4_level,dsdgt4_generate_poly
dude_subdivide_gt4
		sc.sw	ra,sd_gt4_sc_ra
		sc.sw	sd_gt4_pv1,sd_gt4_sc_pv1
		sc.sw	sd_gt4_pv2,sd_gt4_sc_pv2
		sc.sw	sd_gt4_pv3,sd_gt4_sc_pv3

		lh		sd_gt4_temp0,vtx_x(sd_gt4_pv0)
		li		temp,$01010000
		lh		sd_gt4_temp1,vtx_x(sd_gt4_pv1)
		ori		temp,$00000100
		lh		sd_gt4_temp2,vtx_x(sd_gt4_pv2)
		addu	at,sd_gt4_temp0,sd_gt4_temp1
		srl		at,1
		sc.sh	at,sd_gt4_sc_v4+vtx_x
		addu	at,sd_gt4_temp0,sd_gt4_temp2
		lh		sd_gt4_temp3,vtx_x(sd_gt4_pv3)
		srl		at,1
		sc.sh	at,sd_gt4_sc_v5+vtx_x
		addu	at,sd_gt4_temp1,sd_gt4_temp3
		srl		at,1
		sc.sh	at,sd_gt4_sc_v7+vtx_x
		addu	sd_gt4_temp2,sd_gt4_temp3
		srl		at,sd_gt4_temp2,1
		sc.sh	at,sd_gt4_sc_v8+vtx_x
		addu	at,sd_gt4_temp2,sd_gt4_temp0
		lh		sd_gt4_temp0,vtx_y(sd_gt4_pv0)
		addu	at,sd_gt4_temp1
		lh		sd_gt4_temp1,vtx_y(sd_gt4_pv1)
		srl		at,2
		sc.sh	at,sd_gt4_sc_v6+vtx_x
		addu	at,sd_gt4_temp0,sd_gt4_temp1
		lh		sd_gt4_temp2,vtx_y(sd_gt4_pv2)
		srl		at,1
		sc.sh	at,sd_gt4_sc_v4+vtx_y
		addu	at,sd_gt4_temp0,sd_gt4_temp2
		lh		sd_gt4_temp3,vtx_y(sd_gt4_pv3)
		srl		at,1
		sc.sh	at,sd_gt4_sc_v5+vtx_y
		addu	at,sd_gt4_temp1,sd_gt4_temp3
		srl		at,1
		sc.sh	at,sd_gt4_sc_v7+vtx_y
		addu	sd_gt4_temp2,sd_gt4_temp3
		srl		at,sd_gt4_temp2,1
		sc.sh	at,sd_gt4_sc_v8+vtx_y
		addu	at,sd_gt4_temp2,sd_gt4_temp0
		lh		sd_gt4_temp0,vtx_z(sd_gt4_pv0)
		addu	at,sd_gt4_temp1
		lh		sd_gt4_temp1,vtx_z(sd_gt4_pv1)
		srl		at,2
		sc.sh	at,sd_gt4_sc_v6+vtx_y
		addu	at,sd_gt4_temp0,sd_gt4_temp1
		lh		sd_gt4_temp2,vtx_z(sd_gt4_pv2)
		srl		at,1
		sc.sh	at,sd_gt4_sc_v4+vtx_z
		addu	at,sd_gt4_temp0,sd_gt4_temp2
		lh		sd_gt4_temp3,vtx_z(sd_gt4_pv3)
		srl		at,1
		sc.sh	at,sd_gt4_sc_v5+vtx_z
		addu	at,sd_gt4_temp1,sd_gt4_temp3
		srl		at,1
		sc.sh	at,sd_gt4_sc_v7+vtx_z
		addu	sd_gt4_temp2,sd_gt4_temp3
		srl		at,sd_gt4_temp2,1
		sc.sh	at,sd_gt4_sc_v8+vtx_z
		addu	at,sd_gt4_temp2,sd_gt4_temp0
		lw		sd_gt4_temp0,vtx_rgb(sd_gt4_pv0)
		addu	at,sd_gt4_temp1
		lw		sd_gt4_temp1,vtx_rgb(sd_gt4_pv1)
		srl		at,2
		sc.sh	at,sd_gt4_sc_v6+vtx_z
		addu	at,sd_gt4_temp0,sd_gt4_temp1
		xor		sd_gt4_pv1,sd_gt4_temp0,sd_gt4_temp1
		and		sd_gt4_pv1,temp
		lw		sd_gt4_temp2,vtx_rgb(sd_gt4_pv2)
		subu	at,sd_gt4_pv1
		lw		sd_gt4_temp3,vtx_rgb(sd_gt4_pv3)
		srl		at,1
		sc.sw	at,sd_gt4_sc_v4+vtx_rgb
		addu	at,sd_gt4_temp0,sd_gt4_temp2
		xor		sd_gt4_pv1,sd_gt4_temp0,sd_gt4_temp2
		and		sd_gt4_pv1,temp
		subu	at,sd_gt4_pv1
		srl		sd_gt4_temp0,at,1
		sc.sw	sd_gt4_temp0,sd_gt4_sc_v5+vtx_rgb
		addu	at,sd_gt4_temp1,sd_gt4_temp3
		xor		sd_gt4_pv1,sd_gt4_temp1,sd_gt4_temp3
		and		sd_gt4_pv1,temp
		subu	at,sd_gt4_pv1
		srl		sd_gt4_temp1,at,1
		sc.sw	sd_gt4_temp1,sd_gt4_sc_v7+vtx_rgb
		addu	at,sd_gt4_temp0,sd_gt4_temp1
		xor		sd_gt4_pv1,sd_gt4_temp0,sd_gt4_temp1
		and		sd_gt4_pv1,temp
		subu	at,sd_gt4_pv1
		srl		at,1
		sc.sw	at,sd_gt4_sc_v6+vtx_rgb
		addu	at,sd_gt4_temp2,sd_gt4_temp3
		xor		sd_gt4_pv1,sd_gt4_temp2,sd_gt4_temp3
		and		sd_gt4_pv1,temp
		lbu		sd_gt4_temp0,vtx_u(sd_gt4_pv0)
		subu	at,sd_gt4_pv1
		lbu		sd_gt4_temp1,vtx_u(sd_gt4_pv3)
		srl		at,1
		sc.sw	at,sd_gt4_sc_v8+vtx_rgb
		sc.sb	sd_gt4_temp0,sd_gt4_sc_v5+vtx_u
		sc.sb	sd_gt4_temp1,sd_gt4_sc_v7+vtx_u
		lbu		sd_gt4_temp2,vtx_v(sd_gt4_pv0)
		addu	sd_gt4_temp0,sd_gt4_temp1
		lbu		sd_gt4_temp3,vtx_v(sd_gt4_pv3)
		srl		sd_gt4_temp0,1
		sc.sb	sd_gt4_temp2,sd_gt4_sc_v4+vtx_v
		sc.sb	sd_gt4_temp3,sd_gt4_sc_v8+vtx_v
		sc.sb	sd_gt4_temp0,sd_gt4_sc_v4+vtx_u
		sc.sb	sd_gt4_temp0,sd_gt4_sc_v6+vtx_u
		addu	sd_gt4_temp2,sd_gt4_temp3
		srl		sd_gt4_temp2,1
		sc.sb	sd_gt4_temp0,sd_gt4_sc_v8+vtx_u
		sc.sb	sd_gt4_temp2,sd_gt4_sc_v5+vtx_v
		sc.sb	sd_gt4_temp2,sd_gt4_sc_v6+vtx_v
		sc.sb	sd_gt4_temp2,sd_gt4_sc_v7+vtx_v

		addiu	sd_gt4_pv1,scratch,sd_gt4_sc_v4
		addiu	sd_gt4_pv2,scratch,sd_gt4_sc_v5
		addiu	sd_gt4_pv3,scratch,sd_gt4_sc_v6
		jal		dude_subdivide_gt4_
		addiu	scratch,sd_gt4_sc_size

		addiu	sd_gt4_pv0,scratch,sd_gt4_sc_v4-sd_gt4_sc_size
		sc.lw	sd_gt4_pv1,sd_gt4_sc_pv1-sd_gt4_sc_size
		addiu	sd_gt4_pv2,scratch,sd_gt4_sc_v6-sd_gt4_sc_size
		jal		dude_subdivide_gt4_
		addiu	sd_gt4_pv3,scratch,sd_gt4_sc_v7-sd_gt4_sc_size

		addiu	sd_gt4_pv0,scratch,sd_gt4_sc_v5-sd_gt4_sc_size
		addiu	sd_gt4_pv1,scratch,sd_gt4_sc_v6-sd_gt4_sc_size
		sc.lw	sd_gt4_pv2,sd_gt4_sc_pv2-sd_gt4_sc_size
		jal		dude_subdivide_gt4_
		addiu	sd_gt4_pv3,scratch,sd_gt4_sc_v8-sd_gt4_sc_size

		addiu	sd_gt4_pv0,scratch,sd_gt4_sc_v6-sd_gt4_sc_size
		addiu	sd_gt4_pv1,scratch,sd_gt4_sc_v7-sd_gt4_sc_size
		addiu	sd_gt4_pv2,scratch,sd_gt4_sc_v8-sd_gt4_sc_size
		jal		dude_subdivide_gt4_
		sc.lw	sd_gt4_pv3,sd_gt4_sc_pv3-sd_gt4_sc_size

		sc.lw	ra,sd_gt4_sc_ra-sd_gt4_sc_size
		subiu	scratch,sd_gt4_sc_size
		ret
		inc		sd_gt4_level

dsdgt4_generate_poly
		lwc2	C2_VXY0,vtx_xy(sd_gt4_pv0)
		cmpu	polyptr,pblimit
		lwc2	C2_VZ0,vtx_zg(sd_gt4_pv0)
		bhs		.deck
		lw		sd_gt4_temp0,vtx_rgb(sd_gt4_pv0)
		lw		sd_gt4_temp1,vtx_rgb(sd_gt4_pv1)
		gte_rtps
		lwc2	C2_VXY1,vtx_xy(sd_gt4_pv2)
		lwc2	C2_VZ1,vtx_zg(sd_gt4_pv2)
		lwc2	C2_VXY2,vtx_xy(sd_gt4_pv3)
		lwc2	C2_VZ2,vtx_zg(sd_gt4_pv3)
		lw		sd_gt4_temp2,vtx_rgb(sd_gt4_pv2)
		or		sd_gt4_temp0,sd_gt4_code
		lw		sd_gt4_temp3,vtx_rgb(sd_gt4_pv3)
		sw		sd_gt4_temp0,rgb0c(polyptr)
		sw		sd_gt4_temp1,rgb1(polyptr)
		sw		sd_gt4_temp2,rgb2(polyptr)
		if		DEBUG
		sw		r0,rgb3(polyptr)
		else
		sw		sd_gt4_temp3,rgb3(polyptr)
		endif
		lhu		at,vtx_uv(sd_gt4_pv0)
		cfc2	sd_gt4_temp0,C2_FLAG
		lwc2	C2_VXY0,vtx_xy(sd_gt4_pv1)
		lwc2	C2_VZ0,vtx_zg(sd_gt4_pv1)
		mfc2	cl_xy0,C2_SXY2
		nop
		gte_rtpt
		lhu		sd_gt4_pv1,vtx_uv(sd_gt4_pv1)
		or		at,sd_gt4_clut
		lhu		sd_gt4_pv2,vtx_uv(sd_gt4_pv2)
		or		sd_gt4_pv1,sd_gt4_tpage
		lhu		sd_gt4_pv3,vtx_uv(sd_gt4_pv3)
		sw		at,uv0clut(polyptr)
		sw		sd_gt4_pv1,uv1tpg(polyptr)
		sw		sd_gt4_pv2,uv2(polyptr)
		sw		sd_gt4_pv3,uv3(polyptr)
		cfc2	at,C2_FLAG
		nop
		or		at,sd_gt4_temp0
		bltz	at,.skip2
		andi	at,sdflag,4
		bz		.doclip
		nop
		gte_nclip
		mfc2	at,C2_MAC0
		nop
		bmi		.doclip
		andi	sdflag,3
.deck	li		scratch,$1f800000
		b		.skip
		ori		scratch,ins_room_scsize

.doclip	jal		dude_clip4
		pcr.la	cl_jout,.skip

		mfc2	sd_gt4_temp0,C2_SZ0
		mfc2	sd_gt4_temp1,C2_SZ1
		mfc2	sd_gt4_temp2,C2_SZ2
		mfc2	sd_gt4_temp3,C2_SZ3
		gte_avsz4
		sw		cl_xy0,xy0(polyptr)
		sw		cl_xy1,xy1(polyptr)
		cmp		sd_gt4_temp0,sd_gt4_temp1
		bhs		.nz1
		sw		cl_xy2,xy2(polyptr)
		move	sd_gt4_temp0,sd_gt4_temp1
.nz1	cmp		sd_gt4_temp0,sd_gt4_temp2
		bhs		.nz2
		sw		cl_xy3,xy3(polyptr)
		move	sd_gt4_temp0,sd_gt4_temp2
.nz2	cmp		sd_gt4_temp0,sd_gt4_temp3
		bhs		.nz3
		andi	at,sdflag,8
		move	sd_gt4_temp0,sd_gt4_temp3
.nz3	mfc2	sd_gt4_temp1,C2_OTZ
		bz		.nms
		srl		sd_gt4_temp0,OTRIGHT+2
	srl		sd_gt4_temp0,sd_gt4_temp1,OTRIGHT
.nms	sll		sd_gt4_temp0,2
		addu	sd_gt4_temp0,otbase
		lw		sd_gt4_temp1,(sd_gt4_temp0)
		li		at,$0c000000
		or		sd_gt4_temp1,at
		sw		sd_gt4_temp1,(polyptr)
		sw		polyptr,(sd_gt4_temp0)
		addiu	polyptr,gt4_sz
.skip	sc.lw	ra,sd_gt4_sc_ra
		nop
.skip2	ret
		inc		sd_gt4_level

				rsreset
sd_gt3_sc_ra	rw		1
sd_gt3_sc_pv1	rw		1
sd_gt3_sc_pv2	rw		1
sd_gt3_sc_v3	rb		vtx_size
sd_gt3_sc_v4	rb		vtx_size
sd_gt3_sc_v5	rb		vtx_size
sd_gt3_sc_size	rb		0

dude_subdivide_gt3_
		dec		sd_gt3_level
		bltz	sd_gt3_level,dsdgt3_generate_poly
dude_subdivide_gt3
		sc.sw	ra,sd_gt3_sc_ra
		sc.sw	sd_gt3_pv1,sd_gt3_sc_pv1
		sc.sw	sd_gt3_pv2,sd_gt3_sc_pv2

		lh		sd_gt3_temp0,vtx_x(sd_gt3_pv0)
		li		temp,$01010000
		lh		sd_gt3_temp1,vtx_x(sd_gt3_pv1)
		ori		temp,$00000100
		lh		sd_gt3_temp2,vtx_x(sd_gt3_pv2)
		addu	at,sd_gt3_temp0,sd_gt3_temp1
		srl		at,1
		sc.sh	at,sd_gt3_sc_v3+vtx_x
		addu	at,sd_gt3_temp0,sd_gt3_temp2
		lh		sd_gt3_temp0,vtx_y(sd_gt3_pv0)
		srl		at,1
		sc.sh	at,sd_gt3_sc_v4+vtx_x
		addu	at,sd_gt3_temp1,sd_gt3_temp2
		lh		sd_gt3_temp1,vtx_y(sd_gt3_pv1)
		srl		at,1
		sc.sh	at,sd_gt3_sc_v5+vtx_x
		addu	at,sd_gt3_temp0,sd_gt3_temp1
		lh		sd_gt3_temp2,vtx_y(sd_gt3_pv2)
		srl		at,1
		sc.sh	at,sd_gt3_sc_v3+vtx_y
		addu	at,sd_gt3_temp0,sd_gt3_temp2
		lh		sd_gt3_temp0,vtx_z(sd_gt3_pv0)
		srl		at,1
		sc.sh	at,sd_gt3_sc_v4+vtx_y
		addu	at,sd_gt3_temp1,sd_gt3_temp2
		lh		sd_gt3_temp1,vtx_z(sd_gt3_pv1)
		srl		at,1
		sc.sh	at,sd_gt3_sc_v5+vtx_y
		addu	at,sd_gt3_temp0,sd_gt3_temp1
		lh		sd_gt3_temp2,vtx_z(sd_gt3_pv2)
		srl		at,1
		sc.sh	at,sd_gt3_sc_v3+vtx_z
		addu	at,sd_gt3_temp0,sd_gt3_temp2
		lw		sd_gt3_temp0,vtx_rgb(sd_gt3_pv0)
		srl		at,1
		sc.sh	at,sd_gt3_sc_v4+vtx_z
		addu	at,sd_gt3_temp1,sd_gt3_temp2
		lw		sd_gt3_temp1,vtx_rgb(sd_gt3_pv1)
		srl		at,1
		sc.sh	at,sd_gt3_sc_v5+vtx_z
		addu	at,sd_gt3_temp0,sd_gt3_temp1
		xor		sd_gt3_temp3,sd_gt3_temp0,sd_gt3_temp1
		and		sd_gt3_temp3,temp
		subu	at,sd_gt3_temp3
		lw		sd_gt3_temp2,vtx_rgb(sd_gt3_pv2)
		srl		at,1
		sc.sw	at,sd_gt3_sc_v3+vtx_rgb
		addu	at,sd_gt3_temp0,sd_gt3_temp2
		xor		sd_gt3_temp3,sd_gt3_temp0,sd_gt3_temp2
		and		sd_gt3_temp3,temp
		subu	at,sd_gt3_temp3
		lbu		sd_gt3_temp0,vtx_u(sd_gt3_pv0)
		srl		at,1
		sc.sw	at,sd_gt3_sc_v4+vtx_rgb
		addu	at,sd_gt3_temp1,sd_gt3_temp2
		xor		sd_gt3_temp3,sd_gt3_temp1,sd_gt3_temp2
		and		sd_gt3_temp3,temp
		subu	at,sd_gt3_temp3
		lbu		sd_gt3_temp1,vtx_u(sd_gt3_pv1)
		srl		at,1
		sc.sw	at,sd_gt3_sc_v5+vtx_rgb
		addu	at,sd_gt3_temp0,sd_gt3_temp1
		lbu		sd_gt3_temp2,vtx_u(sd_gt3_pv2)
		srl		at,1
		sc.sb	at,sd_gt3_sc_v3+vtx_u
		addu	at,sd_gt3_temp0,sd_gt3_temp2
		lbu		sd_gt3_temp0,vtx_v(sd_gt3_pv0)
		srl		at,1
		sc.sb	at,sd_gt3_sc_v4+vtx_u
		addu	at,sd_gt3_temp1,sd_gt3_temp2
		lbu		sd_gt3_temp1,vtx_v(sd_gt3_pv1)
		srl		at,1
		sc.sb	at,sd_gt3_sc_v5+vtx_u
		addu	at,sd_gt3_temp0,sd_gt3_temp1
		lbu		sd_gt3_temp2,vtx_v(sd_gt3_pv2)
		srl		at,1
		sc.sb	at,sd_gt3_sc_v3+vtx_v
		addu	at,sd_gt3_temp0,sd_gt3_temp2
		srl		at,1
		sc.sb	at,sd_gt3_sc_v4+vtx_v
		addu	at,sd_gt3_temp1,sd_gt3_temp2
		srl		at,1
		sc.sb	at,sd_gt3_sc_v5+vtx_v

		addiu	sd_gt3_pv1,scratch,sd_gt3_sc_v3
		addiu	sd_gt3_pv2,scratch,sd_gt3_sc_v4
		jal		dude_subdivide_gt3_
		addiu	scratch,sd_gt3_sc_size

		addiu	sd_gt3_pv0,scratch,sd_gt3_sc_v3-sd_gt3_sc_size
		sc.lw	sd_gt3_pv1,sd_gt3_sc_pv1-sd_gt3_sc_size
		jal		dude_subdivide_gt3_
		addiu	sd_gt3_pv2,scratch,sd_gt3_sc_v5-sd_gt3_sc_size

		addiu	sd_gt3_pv0,scratch,sd_gt3_sc_v4-sd_gt3_sc_size
		addiu	sd_gt3_pv1,scratch,sd_gt3_sc_v5-sd_gt3_sc_size
		jal		dude_subdivide_gt3_
		sc.lw	sd_gt3_pv2,sd_gt3_sc_pv2-sd_gt3_sc_size

		addiu	sd_gt3_pv0,scratch,sd_gt3_sc_v5-sd_gt3_sc_size
		addiu	sd_gt3_pv1,scratch,sd_gt3_sc_v4-sd_gt3_sc_size
		jal		dude_subdivide_gt3_
		addiu	sd_gt3_pv2,scratch,sd_gt3_sc_v3-sd_gt3_sc_size

		sc.lw	ra,sd_gt3_sc_ra-sd_gt3_sc_size
		subiu	scratch,sd_gt3_sc_size
		ret
		inc		sd_gt3_level

dsdgt3_generate_poly
		lwc2	C2_VXY0,vtx_xy(sd_gt3_pv0)
		lwc2	C2_VZ0,vtx_zg(sd_gt3_pv0)
		lwc2	C2_VXY1,vtx_xy(sd_gt3_pv1)
		lwc2	C2_VZ1,vtx_zg(sd_gt3_pv1)
		lwc2	C2_VXY2,vtx_xy(sd_gt3_pv2)
		cmpu	polyptr,pblimit
		lwc2	C2_VZ2,vtx_zg(sd_gt3_pv2)
		bhs		.deck
		lw		sd_gt3_temp0,vtx_rgb(sd_gt3_pv0)
		lw		sd_gt3_temp1,vtx_rgb(sd_gt3_pv1)
		gte_rtpt
		lw		sd_gt3_temp2,vtx_rgb(sd_gt3_pv2)
		or		sd_gt3_temp0,sd_gt3_code
		sw		sd_gt3_temp0,rgb0c(polyptr)
		sw		sd_gt3_temp1,rgb1(polyptr)
		if		DEBUG
		sw		r0,rgb2(polyptr)
		else
		sw		sd_gt3_temp2,rgb2(polyptr)
		endif
		lhu		sd_gt3_temp0,vtx_uv(sd_gt3_pv0)
		lhu		sd_gt3_temp1,vtx_uv(sd_gt3_pv1)
		or		sd_gt3_temp0,sd_gt3_clut
		lhu		sd_gt3_temp2,vtx_uv(sd_gt3_pv2)
		or		sd_gt3_temp1,sd_gt3_tpage
		sw		sd_gt3_temp0,uv0clut(polyptr)
		sw		sd_gt3_temp1,uv1tpg(polyptr)
		sw		sd_gt3_temp2,uv2(polyptr)
		cfc2	at,C2_FLAG
		nop
		bltz	at,.skip2
		andi	at,sdflag,4
		bz		.doclip
		nop
		gte_nclip
		mfc2	at,C2_MAC0
		nop
		bpl		.doclip
		andi	sdflag,3
.deck	li		scratch,$1f800000
		b		.skip
		ori		scratch,ins_room_scsize

.doclip	jal		dude_clip3
		pcr.la	cl_jout,.skip

		mfc2	sd_gt3_temp0,C2_SZ1
		mfc2	sd_gt3_temp1,C2_SZ2
		mfc2	sd_gt3_temp2,C2_SZ3
		gte_avsz3
		sw		cl_xy1,xy0(polyptr)
		cmp		sd_gt3_temp0,sd_gt3_temp1
		bhs		.nz1
		sw		cl_xy2,xy1(polyptr)
		move	sd_gt3_temp0,sd_gt3_temp1
.nz1	cmp		sd_gt3_temp0,sd_gt3_temp2
		bhs		.nz2
		sw		cl_xy3,xy2(polyptr)
		move	sd_gt3_temp0,sd_gt3_temp2
.nz2	andi	at,sdflag,8
		mfc2	sd_gt3_temp1,C2_OTZ
		bz		.nms
		srl		sd_gt3_temp0,OTRIGHT+2
		srl		sd_gt3_temp0,sd_gt3_temp1,OTRIGHT
.nms	sll		sd_gt3_temp0,2
		addu	sd_gt3_temp0,otbase
		lw		sd_gt3_temp1,(sd_gt3_temp0)
		li		at,$09000000
		or		sd_gt3_temp1,at
		sw		sd_gt3_temp1,(polyptr)
		sw		polyptr,(sd_gt3_temp0)
		addiu	polyptr,gt3_sz
.skip	sc.lw	ra,sd_gt3_sc_ra
		nop
.skip2	ret
		inc		sd_gt3_level

	if	0
dude_wibble
.loop	lhu		wib_tmp,(wib_pvn)
		inc.h	wib_pvn
		srl		wib_tmp,2
		andi	wib_tmp,WIBBLE_MASK
		mac.lbu	wib_tmp,underwater_table+WIBBLE_SIZE(wib_tmp)
		nop
		addu	wib_tmp,wib_idx
		andi	wib_tmp,WIBBLE_MASK
		mac.lb	wib_tmp,underwater_table(wib_tmp)
		lbu		at,vtx_g(wib_pvx)
		addiu	wib_pvx,vtx_size
		addu	wib_tmp,at
		bltz	wib_tmp,.st
		sltiu	at,wib_tmp,$100	; u -> if <0 (s), at=0
		dec		at				; at=$ffffffff if temp4!<$100, else 0
		or		at,wib_tmp
.st		bne		wib_pvn,objptr,.loop
		sb		at,vtx_g-vtx_size(wib_pvx)
		ret
		nop

	endif

dude_insert_mesh_clipped
		gpr.lw	otbase,db+db_ot
		lui		scratch,$1f80
		sc.sw	t0,clut_sub
		gpr.lw	polyptr,db+db_polyptr
		gpr.lh	t0,phd_left
		gpr.lh	t1,phd_right
		sll		t0,16
		gpr.lh	t2,phd_top
		sll		t1,16
		gpr.lh	t3,phd_bottom
		sll		t2,16
		inc		t3
		sll		t3,16
		sc.sw	t0,clip_left
		sc.sw	t1,clip_right
		sc.sw	t2,clip_top
		sc.sw	t3,clip_bottom
		sc.sw	s0,s0_stash
		sc.sw	s1,s1_stash
		sc.sw	s2,s2_stash
		sc.sw	s3,s3_stash
		sc.sw	s4,s4_stash
		sc.sw	s5,s5_stash
		sc.sw	s6,s6_stash
		sc.sw	ra,ra_stash
		gpr.lw	pblimit,db+db_polybuf_limit
		move	sdlimit,v1
		li		sdflag,8

		lh		num,10(objptr)
		addiu	vbase,objptr,12
		bgez	num,.ispos
		clr		nbase
		negate	num
		sll		at,num,2
		addu	at,num
		b		.mk_op
		sll		at,1
.ispos	sll		at,num,3
		addu	nbase,vbase,at
		sll		at,1
.mk_op	addu	objptr,vbase,at

		bz		nbase,.doGT4s
		lhu		objend,(objptr)
		gpr.lw	at,dude_envmap_tpage
		nop
		sc.sw	at,envmap_tpage
.em4lp	inc.h	objptr
		bz		objend,.dnEM4s
		dec		objend
		jal		dude_insert_mesh_quads
		pcr.la	ra,.em4lp
.dnEM4s	lhu		objend,(objptr)
.em3lp	inc.h	objptr
		bz		objend,.dnEM3s
		dec		objend
		jal		dude_insert_mesh_tris
		pcr.la	ra,.em3lp
.dnEM3s	lhu		objend,(objptr)
.doGT4s	inc.h	objptr
		sc.sw	r0,envmap_tpage
.gt4lp	bz		objend,.dnGT4s
		dec		objend
		jal		dude_insert_mesh_quads
		pcr.la	ra,.gt4lp
.dnGT4s	lhu		objend,(objptr)
		inc.h	objptr
.gt3lp	bz		objend,.dnGT3s
		dec		objend
		jal		dude_insert_mesh_tris
		pcr.la	ra,.gt3lp
.dnGT3s	sc.lw	ra,ra_stash
		sc.lw	s0,s0_stash
		sc.lw	s1,s1_stash
		sc.lw	s2,s2_stash
		sc.lw	s3,s3_stash
		sc.lw	s4,s4_stash
		sc.lw	s5,s5_stash
		sc.lw	s6,s6_stash
		ret
		gpr.sw	polyptr,db+db_polyptr

dude_insert_mesh_quads
		lhu		vtx0,(objptr)
		sc.sw	ra,ra_stash2
		addu	norm0,vtx0,nbase
		addu	vtx0,vbase
		lwc2	C2_VXY0,(vtx0)
		lw		vtx0,4(vtx0)
		sc.swc2	C2_VXY0,vertex0+vtx_xy
		mtc2	vtx0,C2_VZ0
		sc.sw	vtx0,vertex0+vtx_zg
		lhu		vtx2,6(objptr)
		gte_rtps
		addu	norm2,vtx2,nbase
		lhu		vtx3,4(objptr)
		addu	vtx2,vbase
		lwc2	C2_VXY1,(vtx2)
		lw		vtx2,4(vtx2)
		addu	norm3,vtx3,nbase
		mtc2	vtx2,C2_VZ1
		lhu		vtx1,2(objptr)
		addu	vtx3,vbase
		lwc2	C2_VXY2,(vtx3)
		lw		vtx3,4(vtx3)
		addu	norm1,vtx1,nbase
		mtc2	vtx3,C2_VZ2
		addu	vtx1,vbase
		mfc2	cxy0,C2_SXY2
		lwc2	C2_VXY0,(vtx1)
		lw		vtx1,4(vtx1)
		sc.swc2	C2_VXY0,vertex1+vtx_xy
		mtc2	vtx1,C2_VZ0
		sc.sw	vtx1,vertex1+vtx_zg
		sc.lw	temp,envmap_tpage
;##		nop	; ##
		gte_rtpt
		bnz		temp,.is_em
		nop
		lhu		temp,8(objptr)
		nop
		sll		temp,4
		sc.lw	at,clut_sub
		addu	temp,txtbase
		lw		vz0,(temp)
		lw		vz1,4(temp)
		subu	vz0,at						;modify clut for underwater
		lw		vz2,8(temp)
		lw		vz3,12(temp)
.is_em	gte_nclip
		cmp		polyptr,pblimit
		bhs		.exit2
		addiu	objptr,10
		sc.sw	vtx2,vertex2+vtx_zg
		sc.sw	vtx3,vertex3+vtx_zg
		mfc2	at,C2_MAC0
		sc.swc2	C2_VXY1,vertex2+vtx_xy
		bpl		.exit2
		sc.swc2	C2_VXY2,vertex3+vtx_xy

		gte_avsz4

		jal		dude_clip4
		pcr.la	cl_jout,.exit

		mfc2	otz,C2_OTZ
		sc.lw	ra,envmap_tpage
;##		nop	;##
		cmpi	otz,(DPQ_END+1)>>2
		bhs		.exit
		sc.lbu	vtx0,vertex0+vtx_g
		bnz		ra,.do_env
		sc.lbu	vtx1,vertex1+vtx_g
		sc.lbu	vtx2,vertex2+vtx_g
		sc.lbu	vtx3,vertex3+vtx_g

		jal		dude_rgb4
		pcr.la	ra,.doit

.do_env	if		0;JAP
		sc.sw	otz,otz_stash
		endif
		lwc2	C2_VXY0,(norm0)
		lwc2	C2_VZ0,4(norm0)
		lhu		at,-2(objptr)
		lhu		vtx0,0(objptr)
		mvmva	1,0,0,3,0
		sll		vtx0,16
		or		vtx0,at
		move	vtx1,vtx0
		move	vtx2,vtx0
		lwc2	C2_VXY1,(norm1)
		move	vtx3,vtx0
		lwc2	C2_VZ1,4(norm1)
		mfc2	vz0,C2_MAC1
		mfc2	at,C2_MAC2
		sra		vz0,7
		sll		at,1
		mvmva	1,0,1,3,0
		if		0;JAP
		sra		temp,at,4
		subu	at,temp
		addiu	at,$7800
		endif
		lwc2	C2_VXY2,(norm2)
		andi	vz0,$00ff
		lwc2	C2_VZ2,4(norm2)
		andi	at,$ff00
		or		vz0,at
		if		0;JAP
		xori	vz0,$0080
		else
		xori	vz0,$8080
		endif
		mfc2	vz1,C2_MAC1
		mfc2	at,C2_MAC2
		sra		vz1,7
		sll		at,1
		mvmva	1,0,2,3,0
		if		0;JAP
		sra		temp,at,4
		subu	at,temp
		addiu	at,$7800
		endif
		lwc2	C2_VXY0,(norm3)
		andi	vz1,$00ff
		lwc2	C2_VZ0,4(norm3)
		andi	at,$ff00
		or		vz1,at
		if		0;JAP
		xori	vz0,$0080
		else
		xori	vz0,$8080
		endif
		or		vz1,ra			;or in tpage
		mfc2	vz2,C2_MAC1
		mfc2	at,C2_MAC2
		sra		vz2,7
		sll		at,1
		mvmva	1,0,0,3,0
		if		0;JAP
		sra		temp,at,4
		subu	at,temp
		addiu	at,$7800
		endif
		andi	vz2,$00ff
		andi	at,$ff00
		or		vz2,at
		if		0;JAP
		xori	vz0,$0080
		else
		xori	vz0,$8080
		endif
		srl		at,vtx0,24
		sll		at,16
		or		vz2,at			;or in code
		mfc2	vz3,C2_MAC1
		mfc2	at,C2_MAC2
		sra		vz3,7
		sll		at,1
		if		0;JAP
		sra		temp,at,4
		subu	at,temp
		addiu	at,$7800
		endif
		andi	vz3,$00ff
		andi	at,$ff00
		or		vz3,at
		if		0;JAP
		sc.lw	otz,otz_stash
		xori	vz0,$0080
		else
		xori	vz0,$8080
		endif

.doit	bltz	sdlimit,.nosd4
		cmpi	otz,SUBDIVIDE_Z>>2
		bhs 	.nosd4

		sc.sw	vz0,vertex0+vtx_uv
		sc.sw	vz1,vertex1+vtx_uv
		sc.sw	vz2,vertex2+vtx_uv
		sc.sw	vz3,vertex3+vtx_uv

		addiu	sd_gt4_pv0,scratch,vertex0
		addiu	sd_gt4_pv1,scratch,vertex1
		addiu	sd_gt4_pv2,scratch,vertex2
		addiu	sd_gt4_pv3,scratch,vertex3

		sw		vtx0,vtx_rgb(sd_gt4_pv0)
		sw		vtx1,vtx_rgb(sd_gt4_pv1)
		sw		vtx2,vtx_rgb(sd_gt4_pv2)
		sw		vtx3,vtx_rgb(sd_gt4_pv3)

		sc.lhu	sd_gt4_clut,vertex0+vtx_p
		bz		sdlimit,.lev1
		clr		sd_gt4_level
		slti	sd_gt4_level,otz,SUBDIVIDE_Z2>>2
.lev1	sc.lhu 	sd_gt4_tpage,vertex1+vtx_p
		sll		sd_gt4_clut,16
		sc.lbu	sd_gt4_code,vertex2+vtx_p+0
		sll		sd_gt4_tpage,16
		sll		sd_gt4_code,24
		jal 	dude_subdivide_gt4
		addiu	scratch,ins_room_scsize
		b		.exit
		subiu	scratch,ins_room_scsize

.nosd4	sw		vz0,uv0clut(polyptr)
		sw		vz1,uv1tpg(polyptr)
		sw		vz2,uv2(polyptr)
		sw		vz3,uv3(polyptr)
		srl		vz2,16
		sll		vz2,24
		or		vtx0,vz2
		sw		vtx0,rgb0c(polyptr)
		sw		vtx1,rgb1(polyptr)
		sw		vtx2,rgb2(polyptr)
		sw		vtx3,rgb3(polyptr)
		sw		cxy0,xy0(polyptr)
		sw		cxy1,xy1(polyptr)
		sw		cxy2,xy2(polyptr)
		sw		cxy3,xy3(polyptr)
		srl		otz,OTRIGHT	;+2
		sll		otz,2
		addu	otz,otbase
		lw		vz0,(otz)
		li		at,$0c000000
		or		vz0,at
		sw		vz0,(polyptr)
		sw		polyptr,(otz)
		addiu	polyptr,gt4_sz

.exit	sc.lw	ra,ra_stash2
		nop
.exit2	ret
		nop

dude_insert_mesh_tris
		lhu		vtx0,(objptr)
		sc.sw	ra,ra_stash2
		lhu		vtx1,2(objptr)
		addu	norm0,vtx0,nbase
		lhu		vtx2,4(objptr)
		addu	vtx0,vbase
		lwc2	C2_VXY0,(vtx0)
		addu	norm1,vtx1,nbase
		lw		vtx0,4(vtx0)
		addu	vtx1,vbase
		sc.swc2	C2_VXY0,vertex0+vtx_xy
		mtc2	vtx0,C2_VZ0
		lwc2	C2_VXY1,(vtx1)
		addu	norm2,vtx2,nbase
		lw		vtx1,4(vtx1)
		addu	vtx2,vbase
		sc.swc2	C2_VXY1,vertex1+vtx_xy
		mtc2	vtx1,C2_VZ1
		lwc2	C2_VXY2,(vtx2)
		lw		vtx2,4(vtx2)
		sc.sw	vtx0,vertex0+vtx_zg
		mtc2	vtx2,C2_VZ2
		sc.sw	vtx1,vertex1+vtx_zg
		sc.lw	temp,envmap_tpage
;##		nop	;##
		gte_rtpt
		bnz		temp,.is_em
		nop
		lhu		temp,6(objptr)
		nop
		sll		temp,4
		sc.lw	at,clut_sub
		addu	temp,txtbase
		lw		vz0,(temp)
		lw		vz1,4(temp)
		subu	vz0,at						;modify clut for underwater
		lw		vz2,8(temp)
.is_em	gte_nclip
		cmp		polyptr,pblimit
		bhs		.exit2
		addiu	objptr,8
		mfc2	at,C2_MAC0
		sc.swc2	C2_VXY2,vertex2+vtx_xy
		bmi		.exit2
		sc.sw	vtx2,vertex2+vtx_zg

		gte_avsz3

		jal		dude_clip3
		pcr.la	cl_jout,.exit

		mfc2	otz,C2_OTZ
		sc.lw	ra,envmap_tpage
;##		nop	;##
		cmpi	otz,(DPQ_END+1)>>2
		bhs		.exit
		sc.lbu	vtx0,vertex0+vtx_g
		bnz		ra,.do_env
		sc.lbu	vtx1,vertex1+vtx_g
		sc.lbu	vtx2,vertex2+vtx_g

		jal		dude_rgb3
		pcr.la	ra,.doit

.do_env	lwc2	C2_VXY0,(norm0)
		lwc2	C2_VZ0,4(norm0)
		lhu		at,-2(objptr)
		lhu		vtx0,0(objptr)
		mvmva	1,0,0,3,0
		sll		vtx0,16
		or		vtx0,at
		move	vtx1,vtx0
		lwc2	C2_VXY1,(norm1)
		move	vtx2,vtx0
		lwc2	C2_VZ1,4(norm1)
		mfc2	vz0,C2_MAC1
		mfc2	at,C2_MAC2
		sra		vz0,7
		sll		at,1
		mvmva	1,0,1,3,0
		if		0;JAP
		sra		vz3,at,4
		subu	at,vz3
		addiu	at,$7800
		endif
		lwc2	C2_VXY2,(norm2)
		andi	vz0,$00ff
		lwc2	C2_VZ2,4(norm2)
		andi	at,$ff00
		or		vz0,at
		if		0;JAP
		xori	vz0,$0080
		else
		xori	vz0,$8080
		endif
		mfc2	vz1,C2_MAC1
		mfc2	at,C2_MAC2
		sra		vz1,7
		sll		at,1
		mvmva	1,0,2,3,0
		if		0;JAP
		sra		vz3,at,4
		subu	at,vz3
		addiu	at,$7800
		endif
		andi	vz1,$00ff
		andi	at,$ff00
		or		vz1,at
		if		0;JAP
		xori	vz0,$0080
		else
		xori	vz0,$8080
		endif
		or		vz1,ra
		mfc2	vz2,C2_MAC1
		mfc2	at,C2_MAC2
		sra		vz2,7
		sll		at,1
		if		0;JAP
		sra		vz3,at,4
		subu	at,vz3
		addiu	at,$7800
		endif
		andi	vz2,$00ff
		andi	at,$ff00
		or		vz2,at
		if		0;JAP
		xori	vz0,$0080
		else
		xori	vz0,$8080
		endif
		srl		at,vtx0,24
		sll		at,24
		or		vz2,at

.doit	bltz	sdlimit,.nosd3
		cmpi	otz,SUBDIVIDE_Z>>2
		bhs 	.nosd3

		sc.sw	vz0,vertex0+vtx_uv
		sc.sw	vz1,vertex1+vtx_uv
		sc.sw	vz2,vertex2+vtx_uv

		addiu	sd_gt3_pv0,scratch,vertex0
		addiu	sd_gt3_pv1,scratch,vertex1
		addiu	sd_gt3_pv2,scratch,vertex2

		sw		vtx0,vtx_rgb(sd_gt4_pv0)
		sw		vtx1,vtx_rgb(sd_gt4_pv1)
		sw		vtx2,vtx_rgb(sd_gt4_pv2)

		sc.lhu	sd_gt3_clut,vertex0+vtx_p
		bz		sdlimit,.lev13
		clr		sd_gt3_level
		slti	sd_gt3_level,otz,SUBDIVIDE_Z2>>2
.lev13	sc.lhu 	sd_gt3_tpage,vertex1+vtx_p
		sll		sd_gt3_clut,16
		sc.lbu	sd_gt3_code,vertex2+vtx_p+1
		sll		sd_gt3_tpage,16
		sll		sd_gt3_code,24
		jal 	dude_subdivide_gt3
		addiu	scratch,ins_room_scsize
		b		.exit
		subiu	scratch,ins_room_scsize

.nosd3
		sw		vz0,uv0clut(polyptr)
		sw		vz1,uv1tpg(polyptr)
		sw		vz2,uv2(polyptr)
		srl		vz2,24
		sll		vz2,24
		or		vtx0,vz2
		sw		vtx0,rgb0c(polyptr)
		sw		vtx1,rgb1(polyptr)
		sw		vtx2,rgb2(polyptr)
		sw		cxy1,xy0(polyptr)
		sw		cxy2,xy1(polyptr)
		sw		cxy3,xy2(polyptr)
		srl		otz,OTRIGHT	;+2
		sll		otz,2
		addu	otz,otbase
		lw		vz0,(otz)
		li		at,$09000000
		or		vz0,at
		sw		vz0,(polyptr)
		sw		polyptr,(otz)
		addiu	polyptr,gt3_sz

.exit	sc.lw	ra,ra_stash2
		nop
.exit2	ret
		nop
