gxclip_ln.s 7 KB
/*---------------------------------------------------------------------*
	Copyright (C) 1998, Nintendo.
	
	File		gxclip_ln.s
	Coded    by	Yoshitaka Yasumoto.	Mar 12, 1998.
	
	$Id: gxclip_ln.s,v 1.1.1.1 2002/05/02 03:29:11 blythe Exp $
 *---------------------------------------------------------------------*/	
 #!Reserved  (0,11,12,22,23,24,25,26,27,31)
 #!Reserved  (v0,v1,v29,v30,v31)

	#---------------------------------------------------------------------
	#  Clipping 処理
	#---------------------------------------------------------------------
caseLN_Clipping:
  FixedAssign(num,   1)		# gxvtx_ex 用レジスタ
  FixedAssign(fogon, 7)		# gxvtx_ex 用レジスタ
  FixedAssign(dest2, 8)		# gxvtx_ex 用レジスタ
  FixedAssign(cflag, 10)	# gxvtx_ex 用レジスタ
  FixedAssign(lstat, 13)	# gxvtx_ex 用レジスタ
  FixedAssign(src,   14)	# gxvtx_ex 用レジスタ
  FixedAssign(dest,  15)	# gxvtx_ex 用レジスタ
  Assign(plane, 6)
	_liu	(plane, 20)
	_liu	(dest, RSP_WORK_CLIPVTX)
LNClip_InitPlane:
	#---------------------------------------------------------------------
	#  Clipping 平面との交差判定
	#---------------------------------------------------------------------
	#------ CC/CCmask の取得 ------
  Assign(cc1, 9)
  Assign(cc2, 16)
	lw	sys0, RSP_SUBMOD_LN_CLIPMASK(plane)
	lw	cc1,  oRSP_POINT_CC(v1)
	lw	cc2,  oRSP_POINT_CC(v2)
	and	cc1,  cc1, sys0
	and	cc2,  cc2, sys0
	beq	cc1,  cc2, LNClip_NextPlane	# 等号成立は双方 0 のときのみ
	sll	sys0, plane, 1

	#------ v1 を内側 v2 を外側にする ------
	beq	cc1,  zero, LNClip_NewVtx
	_mov	(sys1, v1)
	_mov	(v1,   v2)
	_mov	(v2, sys1)
  EndAssign(cc1, 9)
  EndAssign(cc2, 16)
	#---------------------------------------------------------------------
	#  交差する点の取得
	#---------------------------------------------------------------------
LNClip_NewVtx:
  Assign(selp, v2)
  Assign(seln, v3)
  Assign(vtx1f, v4)
  Assign(vtx1i, v5)
  Assign(vtx2f, v6)
  Assign(vtx2i, v7)
  Assign(topf, v8)
  Assign(topi, v9)
  Assign(botf, v10)
  Assign(boti, v11)
	#------ Clip 平面式の係数取得 ------
	ldv	selp[0], RSP_LSTAT_CLIPSELECT(sys0)
	#------ 頂点 v0,v1 の座標取得 ------
	ldv	vtx1f[0], oRSP_POINT_XF(v1)
	ldv	vtx1i[0], oRSP_POINT_XI(v1)
	ldv	vtx2f[0], oRSP_POINT_XF(v2)
	ldv	vtx2i[0], oRSP_POINT_XI(v2)
	#------ 分子分母の計算 ------
	vmudh	seln, selp, _0xffff
	vmudn	topf, vtx1f, selp
	vmadh	topi, vtx1i, selp
	vmadn	botf, vtx2f, seln
	vmadh	boti, vtx2i, seln
  EndAssign(selp, v2)
  EndAssign(seln, v3)
  Assign(vconstTmp, v2)
	vaddc	topf, topf, topf[0q]
		lqv	vconstTmp[0], RSP_LSTAT_VCONST_TMP(zero)
	vadd	topi, topi, topi[0q]	
	vaddc	botf, botf, botf[0q]
	vadd	boti, boti, boti[0q]
	vaddc	topf, topf, topf[1h]
	vadd	topi, topi, topi[1h]	# top[3]=(x1-w1)
	vaddc	botf, botf, botf[1h]
	vadd	boti, boti, boti[1h]	# bot[3]=(x1-x2)-(w1-w2)
	
	#------ スケールファクタの取得 ------
  Assign(wsclf, v3)
  Assign(wscli, v12)
	vrcph	vtmp[0],  boti[3]
	vrcpl	wsclf[3], botf[3]
	vrcph	wscli[3], _0x0000
	#------ 頂点合わせ+絶対値計算 ------
	vabs	vtmp,  boti,  _0x0002	# vtmp[3]=((wscli[3]>=0)?2:-2)
	vmudn	wsclf, wsclf, vtmp[3]
	vmadh	wscli, wscli, vtmp[3]
	#------ 1 未満にまるめる ------
	veq	wscli, wscli, _0x0000	# if   wscl >= 1.0
	vmrg	wsclf, wsclf, _0xffff	# then wscl = 0.99999
  EndAssign(wscli, v12)
	#------ スケールファクタを乗ずる ------
	vmudl	vtmp,  botf,  wsclf[3]
	vmadm	boti,  boti,  wsclf[3]
	vmadn	botf,  vzero, _0x0000
	#
	#  Newton 法を使用し逆数計算を行なう 
	#	vrcph/l で求めるのは 1/2X の値. (R=1/X)
	#	1/X = R*(2-R*X) = R/2*(4+R/2*X*(-4))
	#
  Assign(rbotf, v12)
  Assign(rboti, v13)
  Assign(sbotf, v14)
  Assign(sboti, v15)
	vrcph	rboti[3], boti[3]
	vrcpl	rbotf[3], botf[3]
	vrcph	rboti[3], _0x0000	# R/2
	vmudn	sbotf, rbotf, _0xfffc
	vmadh	sboti, rboti, _0xfffc	# R/2*(-4)
	vmudh	vtmp,  vone,  _0x0004
	vmadl	vtmp,  sbotf, botf
	vmadm	vtmp,  sboti, botf
	vmadn	botf,  sbotf, boti
	vmadh	boti,  sboti, boti	# 4+R/2*X*(-4)
	vmudl	vtmp,  rbotf, botf
	vmadm	vtmp,  rboti, botf
	vmadn	rbotf, rbotf, boti
	vmadh	rboti, rboti, boti	# R/2*(4+R/2*X*(-4))
  EndAssign(vconstTmp, v2)
  EndAssign(botf, v10)
  EndAssign(boti, v11)
  EndAssign(sbotf, v14)
  EndAssign(sboti, v15)
  Assign(nf, v2)
  Assign(ni, v10)
  Assign(st1, v11)
  Assign(st2, v14)
	#------ n=top/bot を求める ------
	vmudl	vtmp, topf, rbotf	luv	st2[0], oRSP_POINT_R(v2)
	vmadm	vtmp, topi, rbotf	llv	st2[8], oRSP_POINT_S(v2)
	vmadn	nf,   topf, rboti	luv	st1[0], oRSP_POINT_R(v1)
	vmadh	ni,   topi, rboti	llv	st1[8], oRSP_POINT_S(v1)
  EndAssign(topf, v8)
  EndAssign(topi, v9)
  EndAssign(rbotf, v12)
  EndAssign(rboti, v13)
	#------ スケールファクタを乗ずる ------
	vmudl	vtmp, nf, wsclf[3]
	vmadm	ni,   ni, wsclf[3]
	vmadn	nf,   nf, _0x0000
  EndAssign(wsclf, v3)
	#------ n をクランプする ------
	#  0x0001 から 0xffff までに納める
	#
	vlt	ni,   ni, _0x0001
	vmrg	nf,   nf, _0xffff
	vsubc	vtmp, nf, _0x0001
	vge	ni,   ni, _0x0000
	vmrg	nf,   nf, _0x0001
  Assign(negnf, v3)
	#------ 1-n の計算 ------
	vmudn	negnf, nf, _0xffff
  EndAssign(ni, v10)
  FixedAssign(vout12f, v23)
  FixedAssign(vout12i, v24)
	#
	#  新頂点座標の計算 v1*(1-n)+v2*n
	#
	vmudl	vtmp,    vtx2f, nf[3]
	vmadm	vtmp,    vtx2i, nf[3]
	vmadl	vtmp,    vtx1f, negnf[3]
	vmadm	vout12i, vtx1i, negnf[3]
	vmadn	vout12f, vzero, _0x0000
  EndAssign(vtx1f, v4)
  EndAssign(vtx1i, v5)
  EndAssign(vtx2f, v6)
  EndAssign(vtx2i, v7)
	#------ 新頂点のアトリビュート値の計算  [R|G|B|A|S|T|-|-] ------
  FixedAssign(st12, v22)
	vmudm	vtmp, st2, nf[3]
	vmadm	st12, st1, negnf[3]
  EndAssign(st1, v11)
  EndAssign(st2, v14)
  EndAssign(nf, v2)
  EndAssign(negnf, v3)
	#-------------------------------------------------------------------
	#  gxvtx_ex と一致するように調整
	#    out12f(v23)
	#    out12i(v24)
	#    fogon(7)  =0
	#    num(1)    =2
	#    dest(15)  頂点キャッシュバッファ(VTX 処理内で +80 される)
	#    st12(v22) gxvtx_ex 内で変化無いので return 後再設定する
	#
	#    GetTrans で以下が取得できる
	#	lstat(13),vpscale(v16),vptrans(v17),txscale(v18),dest2(8)
	#
	#    GetTrans 後 G_VTX_Return へ Jump する.
	#-------------------------------------------------------------------
	_li	(fogon, 0)
	_li	(num,   2)
	_mov	(v2, dest)		# ポインタつけ変え
	j	caseEX_G_VTX_GetTrans
	_li	(return, caseEX_G_VTX_Return+0x8000)
			# return<0 なら vtx 処理後,ここへ戻る
  FixedAssign(vscn12i, v25)
  FixedAssign(vscn12f, v26)
  FixedAssign(vcolor,  v3)
caseEX_ClipRet:
	#------ 残りパラメータの書き込み ------
#ifndef	NO_CLAMP_Z
	slv	vscn12i[0],  24-80(dest)  # Xs,Ys1
#else
	sdv	vscn12i[0],  24-80(dest)  # Xs,Ys,Zs1
#endif
	ssv	vscn12f[4],  30-80(dest)  # Zsf1
	suv	st12[0],     16-80(dest)  # R,G,B,A
	slv	st12[8],     20-80(dest)  # S,T
#ifndef	NO_CLAMP_Z
	ssv	vcolor[4],   28-80(dest)  # Zs1
#endif
	addi	dest,  dest,  -40	
  EndAssign(st12, v22)
  EndAssign(vout12f, v23)
  EndAssign(vout12i, v24)
  EndAssign(vscn12i, v25)
  EndAssign(vscn12f, v26)
  EndAssign(vcolor,  v3)
LNClip_NextPlane:
	#------ 次のクリップ面へ ------
	bne	plane, zero, LNClip_InitPlane
	addi	plane, plane, -4
  EndAssign(num, 1)
  EndAssign(src, 14)
  EndAssign(dest, 15)
  EndAssign(lstat, 13)
  EndAssign(fogon, 7)
  EndAssign(dest2, 8)
  EndAssign(cflag, 10)
  EndAssign(plane, 6)
	
/*======== End of gxclip_ln.s ========*/