gxlight_flxrej.s 10.2 KB
/*---------------------------------------------------------------------*
	Copyright (C) 1998, Nintendo.
	
	File		gxlight_flxrej.s
	Coded    by	Yoshitaka Yasumoto.	Mar 31, 1998.
	
	$Id: gxlight_flxrej.s,v 1.1.1.1 2002/05/02 03:29:11 blythe Exp $
 *---------------------------------------------------------------------*/

	#---------------------------------------------------------------------
	#  FZEROX 用ライト処理
	#	Defuse ライトは 1 つに固定
	#	G_TEXTURE_GEN を立てると HiLight 処理を行なう.
	#	ライトの方向の内部計算を 8bit から 16bit に変更.
	#---------------------------------------------------------------------

	#---------------------------------------------------------------------
	#
	#	+-------------+
	#	|             |
	#	+-------------+ RSP_LSTAT_LOOKATY
	#	|  Hilight    |
	#	+-------------+ RSP_LSTAT_L_0
	#	|  Defuse1    |
	#	+-------------+ RSP_LSTAT_L_1
	#	|  Ambient    |
	#	+-------------+
	#	+-------------+ (RSP_LSTAT_L_2+15)&0xff0+0
	#	|    Dummy    |
	#	+-------------+ (RSP_LSTAT_L_2+15)&0xff0+16
	#	| Hilight Dir |
	#	+-------------+ (RSP_LSTAT_L_2+15)&0xff0+32
	#	| Defuse1 Dir |
	#	+-------------+
	#
	#	Hilight	24Bytes
	#	typedef	struct {
	#		unsigned short	offset; 
	#		unsigned short	slope;
	#		unsigned long	pad1; 
	#		signed   short	dir[3];
	#		signed   short	pad2;
	#		unsigned long	pad3, pad4; 
	#	}
	#---------------------------------------------------------------------
	.symbol	RSP_LSTAT_DIR16, (RSP_LSTAT_L_2+15)&0xff0	# align 16
	
	#---------------------------------------------------------------------
	#  ライトの変換処理
	#	ライトの方向ベクトルに対し, MMtx の回転要素 3x3 の転置行列
	#	を乗じることで, ライトベクトルをモデルのローカル座標系に
	#	変換する.
	#---------------------------------------------------------------------
  FixedAssign(gmode_h, 5)	/* gxvtx_ex.s と共用 */
  FixedAssign(lighton, 6)	/* gxvtx_ex.s と共用 */
caseLXRej_XfmLight:
		#-------------------------------------------------------------
		#  Light 計算をする必要があるかを判定し, Light 計算が必要な
		#  ければ終了する.
		#	フラグに 0 以外の値を代入し処理済みにする.
		#	gfx0 の最下位バイトは 0 でないのでこれで OK
		#-------------------------------------------------------------
		lbu	sys0,     RSP_LSTAT_LIGHT_FLAG(zero)
		sb	gfx0,     RSP_LSTAT_LIGHT_FLAG(zero) # フラグを非 0 にする
		_li	(lighton, RSP_LSTAT_DIR16)
		#-------------------------------------------------------------
		#  3x3 転置マトリクスを取得.
		#  ライトの数/ライトデータへのポインタの計算
		#-------------------------------------------------------------
  FixedAssign(lptr, 20)
  Assign(ldir, v7)
  Assign(mtx0, v8)
  Assign(mtx1, v9)
  Assign(mtx2, v10)
  Assign(mtf0, v12)
  Assign(mtf1, v13)
  Assign(mtf2, v14)
		bne	sys0, zero, caseLXRej_G_VTX_MulMP
						lqv	mtf0[0], RSP_GSTAT_MMTX+32+0(zero)
						lqv	mtx0[0], RSP_GSTAT_MMTX+ 0+0(zero)
						lsv	mtf1[2], RSP_GSTAT_MMTX+40+2(zero)
						lsv	mtx1[2], RSP_GSTAT_MMTX+ 8+2(zero)
		vmov	mtf1[0], mtf0[1]	lsv	mtf2[4], RSP_GSTAT_MMTX+48+4(zero)
		vmov	mtx1[0], mtx0[1]	lsv	mtx2[4], RSP_GSTAT_MMTX+16+4(zero)
		vmov	mtf2[0], mtf0[2]	_mov	(lptr, lighton)		# Hilight Dir
		vmov	mtx2[0], mtx0[2]	ldv	ldir[0], 8+RSP_LSTAT_LOOKATY-RSP_LSTAT_DIR16(lighton)
		vmov	mtf2[1], mtf0[6]	lsv	mtf1[4], RSP_GSTAT_MMTX+48+2(zero)
		vmov	mtx2[1], mtx0[6]	lsv	mtx1[4], RSP_GSTAT_MMTX+16+2(zero)
		vmov	mtf0[1], mtf0[4]	lsv	mtf0[4], RSP_GSTAT_MMTX+48+0(zero)
		vmov	mtx0[1], mtx0[4]	lsv	mtx0[4], RSP_GSTAT_MMTX+16+0(zero)

		#-------------------------------------------------------------
		#  ライトベクトルの行列変換
		#	光線ベクトルを取得し, 3x3 転置行列を乗ずる.
		#	これにより World 座標から Model 座標へと変換される.
		#  結果の保存
		#	nx,ny,nz 値を 2 箇所に保存する.
		#	---> FZEROX 変更: 16bit 値として保存する
		#-------------------------------------------------------------
  Assign(ndirf, v11)
  Assign(ndiri, v15)
XfmLightLoop_lxrej:
		vmudn	vtmp,  mtf1,  ldir[1]		_li	(sys1, RSP_LSTAT_DIR16+32)
		vmadh	vtmp,  mtx1,  ldir[1]		
		vmadn	vtmp,  mtf0,  ldir[0]		sdv	ndiri[0], 0(lptr) # 初回は Dummy へ書き込む
		vmadh	vtmp,  mtx0,  ldir[0]		sdv	ndiri[0], 8(lptr)
		vmadn	vtmp,  mtf2,  ldir[2]		beq	lptr, sys1, caseLXRej_G_VTX_MulMP
		vmadh	vtmp,  mtx2,  ldir[2]		/* Delay */
		vsar	ndirf, ndirf, ndirf[1]		addi	lptr, lptr, 16
		vsar	ndiri, ndiri, ndiri[0]
		
		#-------------------------------------------------------------
		#  ライトベクトルの正規化
		#	ベクトルの大きさの 2 乗値を求め, その平方根の逆数を
		#	求める. その値を各要素に乗ずる. そのとき要素の値域が,
		#	0x7fff から -0x8000 となるように予め小数点の位置を操
		#	作しておく.
		#-------------------------------------------------------------
  Assign(invsqf, v16)
  Assign(invsqi, v17)
  Assign(vtmpf,  v18)
		#---- 各要素の 2 乗 ----
		vmudl	vtmp,   ndirf,  ndirf
		vmadm	vtmp,   ndiri,  ndirf
		vmadn	invsqf, ndirf,  ndiri
		vmadh	invsqi, ndiri,  ndiri
		#---- 2 乗値の合計 ----
		vaddc	vtmpf,  invsqf, invsqf[1]
		vadd	vtmp,   invsqi, invsqi[1]
		vaddc	invsqf, vtmpf,  invsqf[2]
		vadd	invsqi, vtmp,   invsqi[2]
		#---- 平方根の逆数 (s8.23) ----	#---- Defuse 1 の取得 ----
		vrsqh	vtmp  [0], invsqi[0]	lpv	ldir[0], 8+RSP_LSTAT_L_0-RSP_LSTAT_DIR16(lighton)
		vrsql	invsqf[0], invsqf[0]
		vrsqh	invsqi[0], _0x0000
		#---- 各要素への乗算 (s15.16)x(s8.23)=(s8.23) ----
		vmudl	vtmp,  ndirf, invsqf[0]
		vmadm	vtmp,  ndiri, invsqf[0]
		vmadn	ndirf, ndirf, invsqi[0]
		vmadh	ndiri, ndiri, invsqi[0]
		#---- 小数点の移動 (s8.23)->(s0.31) ----
		vmudn	ndirf, ndirf, _0x0100
		j	XfmLightLoop_lxrej
		vmadh	ndiri, ndiri, _0x0100	# +7fff 〜 -8000 でクランプ

  EndAssign(invsqf, v16)
  EndAssign(invsqi, v17)
  EndAssign(vtmpf,  v18)	
  EndAssign(ndirf,  v11)
  EndAssign(ndiri,  v15)
  EndAssign(lptr, 20)
  EndAssign(ldir, v7)
  EndAssign(mtx0, v8)
  EndAssign(mtx1, v9)
  EndAssign(mtx2, v10)
  EndAssign(mtf0, v12)
  EndAssign(mtf1, v13)
  EndAssign(mtf2, v14)

	#---------------------------------------------------------------------
	#  頂点カラーの計算
	#---------------------------------------------------------------------
caseLXRej_Lighting:
  FixedAssign(lptr,   9)
  FixedAssign(src,    14)	/* gxvtx_ex.s と共用 */
  FixedAssign(lstat,  13)	/* gxvtx_ex.s と共用 */
  FixedAssign(st12,  v22)	/* gxvtx_ex.s と共用 */
  FixedAssign(normX,  v7)	
  FixedAssign(normY,  v6)
  FixedAssign(normZ,  v5)
  FixedAssign(color1, v4)
  FixedAssign(color2, v3)
  FixedAssign(ldir1,  v2)
  FixedAssign(ldir2, v20)	/* Vtx では vin12i  */
  FixedAssign(dotp1, v21)	/* Vtx では vin12f  */
  FixedAssign(dotp2, v28)
  FixedAssign(vscn12i, v25)	/* gxvtx_ex.s と共用 */
  FixedAssign(vscn12f, v26)	/* gxvtx_ex.s と共用 */
  FixedAssign(normXu,  v27)
  EndAssign(vtmp, v29)
  FixedAssign(sumcol, v29)	/* Vtx では vtmp    */
  FixedAssign(num,    1)
  FixedAssign(cflag,  2)
  FixedAssign(dest2,  8)
  FixedAssign(dest2x, 10)
	#---- 法線ベクトルの取得 ----		#---- gxvtx.s で lptr = RSP_LSTAT_DIR16
	vadd	normY,  vzero,   normX[1h]	luv	normXu[0],  8(src)
	vadd	normZ,  vzero,   normX[2h]	lqv	color2[0], 16(lptr)
	vne	color1, vconst0, vconst0[3h]	luv	sumcol[0],  0+RSP_LSTAT_L_1    -RSP_LSTAT_DIR16(lptr)
	#---- Light と法線の内積計算 (結果を正にクランプする) ----
	vmulu	dotp1,  normX, ldir1[0h]	luv	color1[0],  0+RSP_LSTAT_L_0    -RSP_LSTAT_DIR16(lptr)
	vmacu	dotp1,  normY, ldir1[1h]	ldv	ldir2[0],   0+RSP_LSTAT_LOOKATY-RSP_LSTAT_DIR16(lptr)
	vmacu	dotp1,  normZ, ldir1[2h]	ldv	ldir2[8],   0+RSP_LSTAT_LOOKATY-RSP_LSTAT_DIR16(lptr)
	#---- HiLight パラメータ計算 (内積計算) ----
	vmulf	dotp2,  normX, color2[0h]	andi	cflag, gmode_h, G_TEXTURE_GEN_H
	vmacf	dotp2,  normY, color2[1h]	  addi	num, num, -2*2		# num 値を減算する
	vmacf	dotp2,  normZ, color2[2h]	  sdv	vscn12i[8], oRSP_POINT_XS-RSP_POINT_LEN*1-4(dest2x) /*XZs2*/
	#---- 
	vmrg	sumcol, sumcol, normXu		  sdv	vscn12i[0], oRSP_POINT_XS-RSP_POINT_LEN*2(dest2)    /*XZs1*/
	#----
	vand	dotp1,  dotp1,  _0x7fff		  ssv	vscn12f[12],oRSP_POINT_ZSF-RSP_POINT_LEN*1(dest2)   /*Zsf2*/
	#----
  EndAssign(normXu, v27)
  EndAssign(ldir1,  v2)
  FixedAssign(vfog12, v27)	/* gxvtx_ex.s と共用 */
  FixedAssign(yscn12i, v2)
	vge	vfog12,  vscn12i, _0x7f00	  ssv	vscn12f[4], oRSP_POINT_ZSF-RSP_POINT_LEN*2(dest2)   /*Zsf1*/
						#---- 内積値を S reg へ移動 ----
	vand	yscn12i, vscn12i, _0xfffc	spv	dotp2[0], 0+RSP_LSTAT_L_2-RSP_LSTAT_DIR16(lptr)
	#---- カラー値の加算 ----
#define	alpha1	sys1
#define	alpha2	lptr
	vmulf	sumcol, sumcol, _0x7fff		lb	alpha1,   0+RSP_LSTAT_L_2-RSP_LSTAT_DIR16(lptr)
	vmacf	sumcol, color1, dotp1[0h]	lb	alpha2,   4+RSP_LSTAT_L_2-RSP_LSTAT_DIR16(lptr)
  EndAssign(normY,  v6)
  EndAssign(normZ,  v5)
  EndAssign(color1, v4)
  EndAssign(color2, v3)
  EndAssign(dotp1,  v21)	/* Vtx では vin12f  */
  EndAssign(normX,  v7)
  Assign(W12f, v3)
  Assign(W12i, v4)
  Assign(vclip12f, v5)
  Assign(vclip12i, v6)
  FixedAssign(txscale, v18)
#define	pNorm	txscale[4]
#define	clipBox	txscale[5]
  FixedAssign(vout12f, v23)
  FixedAssign(vout12i, v24)
  FixedAssign(invW12f, v7)
  FixedAssign(fogon, 7)
#define	vtmp	sumcol
	vmudl	W12i, vout12f, pNorm		llv	st12[4],   24(src)
	vmadm	W12i, vout12i, pNorm		lbu	alpha1, RSP_SAVE_ALTBL_OFFSET(alpha1)
	vmadn	W12f, vzero,   _0x0000		lbu	alpha2, RSP_SAVE_ALTBL_OFFSET(alpha2)
  	vmudn	vclip12f, vout12f, clipBox	sub	sys0, dest2, fogon	# Fog=OFF なら Ys の位置に書き込む.
	vmadh	vclip12i, vout12i, clipBox	beq	cflag, zero, caseLXRej_G_VTX_Return1
	/*Delay*/				suv	sumcol[0],  8(src)  # カラー値の出力
	vrcph	vtmp[0],    W12i[3]		sb	alpha1,    11(src)
	vrcpl	invW12f[3], W12f[3]		j	caseLXRej_G_VTX_Return2
	/*Delay*/				sb	alpha2,    15(src)
#undef	vtmp
  EndAssign(sumcol, v29)	/* Vtx では vtmp    */
  FixedAssign(vtmp, v29)
  EndAssign(ldir2,  v20)
  EndAssign(fogon, 7)
  EndAssign(num,   1)
  EndAssign(cflag, 2)
  EndAssign(dest2, 8)
  EndAssign(dest2x, 10)
  EndAssign(yscn12i, v2) 
  EndAssign(W12f, v3)
  EndAssign(W12i, v4)
  EndAssign(vclip12f, v5)
  EndAssign(vclip12i, v6)
  EndAssign(invW12f, v7)
  EndAssign(txscale, v18)
#undef	pNorm
#undef	clipBox
  EndAssign(vout12f, v23)
  EndAssign(vout12i, v24)
  EndAssign(vscn12f, v26)
  EndAssign(lptr,    9)
  EndAssign(lstat,  13)		/* gxvtx_ex.s と共用 */
  EndAssign(gmode_h, 5)		/* gxvtx_ex.s と共用 */
  EndAssign(lighton, 6)		/* gxvtx_ex.s と共用 */
  EndAssign(src,    14)		/* gxvtx_ex.s と共用 */
  EndAssign(st12,   v22)
  EndAssign(dotp2,  v28)
  EndAssign(vscn12i,v25)	/* gxvtx_ex.s と共用 */
  EndAssign(vfog12, v27)	/* gxvtx_ex.s と共用 */
	
/*======== End of gxlight_flxrej.s ========*/