gxline_ln.s 10.8 KB
 #----------------------------------------------------------------------#
 #	Copyright (C) 1998, Nintendo.
 #	
 #	File		gxline_ln.s
 #	Coded    by	Yoshitaka Yasumoto.	Mar 17, 1998.
 #	
 #	$Id: gxline_ln.s,v 1.1.1.1 2002/05/02 03:29:11 blythe Exp $
 #----------------------------------------------------------------------#
#if 0
 #!Reserved  (0,2,3,4,5,11,12,22,23,24,25,26,27,28,29,30,31)
 #!Reserved  (v0,v1,v29,v30,v31)
  FixedAssign(v1, 2)
  FixedAssign(v2, 3)
  FixedAssign(wd, 4)
  FixedAssign(flat, 5)
#endif
	#---------------------------------------------------------------------
	#  Line Setup 処理
	#---------------------------------------------------------------------
  Assign(flag, 1)
  Assign(txflag, 6)
  Assign(miny, 7)
  Assign(maxy, 8)
  Assign(aminf, v2)
  Assign(amaxf, v3)
		#---- 入力頂点の Y 座標によるソート	# amaxf=0x8000 は後で使う
		lh	miny, oRSP_POINT_YS(v1)		vnxor	aminf, vzero, _0x7fff
		lh	maxy, oRSP_POINT_YS(v2)		vnxor	amaxf, vzero, _0x7fff
				#---- RENDER フラグ取得
				lw	flag,   RSP_LSTAT_RENDER(zero)
				lbu	txflag, RSP_LSTAT_TEX_ENABLE(zero)
		sub	sys0, maxy, miny
		bgez	sys0, setupLN_0
		  _mov	(sys0, v1)
		  _mov	(v1,   v2)
		  _mov	(v2, sys0)
  Assign(vmin, v4)
  Assign(vmax, v5)
  Assign(amin, v6)
  Assign(amax, v7)
setupLN_0: 	#---- XY 座標取得 vmin/vmax[0|1]
		llv	vmin[0], oRSP_POINT_XS(v1)
		llv	vmax[0], oRSP_POINT_XS(v2)
		#---- Flat/Smooth の判定
		sll     sys0, flag, 10		# G_SHADING_SMOOTH=0x00200000
		bgez    sys0, setupLN_flat
		#---- タイルの取得
  Assign(tile, 9)
		lbu	tile,   RSP_LSTAT_TEX_TILE(zero)	# Delay
		#---- XY 座標差分,最大計算		#---- Color 値の取得 [0-3](Smooth)
  Assign(vH, v8)
  Assign(vmaxx, v9)
  Assign(vminx, v10)
  Assign(vHabs, v11)
  Assign(scis, v12)
		vsub	vH,    vmax, vmin		lpv	amin[0], oRSP_POINT_R(v1)
		vge	vmaxx, vmax, vmin		j	setupLN_smooth
		/*Delay*/				lpv	amax[0], oRSP_POINT_R(v2)
setupLN_flat:	#---- XY 座標差分,最大計算		#---- Color 値の取得 [0-3] (Flat)
		/*V*/					lpv	amin[0], oRSP_POINT_R(flat)
		vsub	vH,    vmax, vmin		lbv	amin[6], oRSP_POINT_A(v1)
		vge	vmaxx, vmax, vmin		lpv	amax[0], oRSP_POINT_R(flat)
		/*V*/					lbv	amax[6], oRSP_POINT_A(v2)
setupLN_smooth:	#---- シザリングパラメータ取得		#---- 差分の絶対値の計算,最小値計算
		_li	(sys0, RSP_SUBMOD_LN_SCIS_XL)	vabs	vHabs, vH, vH
		ldv	scis[0], 0(sys0)		vlt	vminx, vmax, vmin
		#---- Z 座標値の取得 amin/amax[7]	#---- Color 値の小数点あわせ
		lsv     aminf[14], oRSP_POINT_ZSF(v1)	vmudl   amin, amin, _0x0100
		lsv     amaxf[14], oRSP_POINT_ZSF(v2)	vmudl   amax, amax, _0x0100
		#					#---- 逆数計算
  Assign(invDf, v13)
  Assign(invDi, v14)
		lsv	amin[14],  oRSP_POINT_ZS(v1)	vrcp	invDf[1], vH[1]
		lsv	amax[14],  oRSP_POINT_ZS(v2)	vrcph	invDi[1], _0x0000
		#---- テクスチャ座標値の取得 amin/amax[4|5]
		llv	amin[8],   oRSP_POINT_S(v1)	vrcp	invDf[0], vH[0]
		llv	amax[8],   oRSP_POINT_S(v2)	vrcph	invDi[0], _0x0000
		#----					#---- Attr 値の差分の計算
  Assign(aDelf, v15)
  Assign(aDeli, v16)
		/*S*/					vsubc	aDelf, amaxf, aminf
		/*S*/					vsub	aDeli, amax,  amin
  EndAssign(amax, v7)
  Assign(dx, 10)
  Assign(dy, 13)
		#---- 縦横の判定			#---- 逆数値の小数点あわせ
		mfc2	dx, vHabs[0]			vmudl	vtmp,  invDf, _0x0008
		mfc2	dy, vHabs[2]			vmadm	invDi, invDi, _0x0008
  EndAssign(vHabs, v11)
		#---- シザリングパラメータの設定	#
		ldv	scis[8],RSP_GSTAT_SCISSOR(zero)	vmadn	invDf, vzero, _0x0000
		#---- フラグのマージ			#---- vH の小数点あわせ
  Assign(DxDyf, v7)
  Assign(DxDyi, v11)
		or	flag, flag, txflag		vmudm	DxDyi, vH,    _0x4000
		ori	flag, flag, G_TRI_FILL		vmadn	DxDyf, vzero, _0x0000
  EndAssign(txflag, 6)
  Assign(DaDef, v17)
  Assign(DaDei, v18)
		#					#---- DaDe 値の計算
		sb	flag, 0+8(outp)			vmudn	vtmp,  aDelf, invDi[1]
		#---- ライン幅の取得			#
  Assign(vwidth, v19)
		mtc2	wd, vwidth[0]			vmadm	vtmp,  aDeli, invDf[1]
		#---- シザリングパラメータのリセット	#
		sdv	scis[8], 0(outp)		vmadl	DaDef, aDelf, invDf[1]
		#---- dx>dy なら横方向			#
		sub	sys0, dx, dy			vmadh	DaDei, aDeli, invDi[1]
  EndAssign(dx, 10)
  EndAssign(dy, 13)
		#---- DaDe 値の W を 0 クリアする	#---- DxDyH の計算 [0]
		mtc2	zero, DaDef[12]			vmudl	vtmp,  DxDyf, invDf[1]
		mtc2	zero, DaDei[12]			vmadm	vtmp,  DxDyi, invDf[1]
		#---- 描画手法によって Jump する	#
		/*Resv*/				vmadn	DxDyf, DxDyf, invDi[1]
		bgtz	sys0, setupLN_Horiz		/*Resv*/
		/*Delay*/				vmadh	DxDyi, DxDyi, invDi[1]
		#--------------------------------------------------------
		#  縦方向ラインの作画
		#--------------------------------------------------------	
  Assign(xHf, v20)
  Assign(xHi, v21)
setupLN_Vert:	#---- サブピクセル計算 yf[1]を使用
		vmudn	xHf, vmin, _0x4000		/*S*/
		#---- DaDx = 0, DaDy = DaDe		#---- outp への出力 (Major=0x00固定)
  Assign(DaDxf, v22)
  Assign(DaDxi, v23)
  Assign(DaDyf, v24)
  Assign(DaDyi, v25)
		vadd	DaDxf, vzero, _0x0000		sb	tile,      1+8(outp)
		vadd	DaDxi, vzero, _0x0000		ssv	vmax[2],   2+8(outp)
		vadd	DaDyf, DaDef, _0x0000		ssv	vmax[2],   4+8(outp)
		vadd	DaDyi, DaDei, _0x0000		jal	setupLN_Attr
		/*Delay*/				ssv	vmin[2],   6+8(outp)
		#---- ライン幅の設定 xH=x-wid xM=x+wid	#
		#	ACC に X が入っている		#
		#			amaxf[0]=0x8000	#
  Assign(xMf, v26)
  Assign(xMi, v27)
		vmadn	xHf, vwidth, _0x4000		ssv	DxDyf[0], 22+8(outp)		
		vmadh	xHi, vzero,  _0x0000		ssv	DxDyi[0], 20+8(outp)
		vmadn	xMf, vwidth, amaxf[0]		ssv	DxDyf[0], 30+8(outp)
		vmadh	xMi, vzero,  _0x0000		j	setupLN_Exit
		/*Delay*/				ssv	DxDyi[0], 28+8(outp)

		#--------------------------------------------------------
		#  横方向ラインの作画
		#--------------------------------------------------------
setupLN_Horiz:
		#---- シザリングパラメータ決定		#---- Major 判定
  Assign(v0100, v28)
		vge	vminx, vminx, scis[0]		mfc2	sys0, vH[0]	#sys0=x2-x1
		vlt	vmaxx, vmaxx, scis[2]
		vadd	v0100, vzero, _0x0100
						vabs	DaDxi, DxDyi, DxDyi
		vmudl	vtmp,  v0100, scis[1]		slt	sys0, sys0, zero
		vmadn	vminx, vminx, _0x0010		sll	sys0, sys0, 7
		vmudl	vtmp,  v0100, scis[3]		or	tile, tile, sys0
		vmadn	vmaxx, vmaxx, _0x0010		sb	tile, 1+8(outp)
  EndAssign(v0100, v28)
		#---- DaDx の計算
		vmudl	vtmp,  aDelf, invDf[0]	mfc2	sys1, DaDxi[0]
		vmadm	vtmp,  aDeli, invDf[0]		addi	sys0, outp, 1
		vmadn	DaDxf, aDelf, invDi[0]		ssv	vminx[0], 1-1(sys0)
		vmadh	DaDxi, aDeli, invDi[0]		ssv	vmaxx[0], 5-1(sys0)
  EndAssign(invDf, v13)
  EndAssign(invDi, v14)
		#---- Y 座標計算			#---- 真横のラインかどうかの判定
  Assign(yL, v28)
  Assign(yH, v13)
  Assign(yM, v14)
		vadd	yM, vmin, vwidth[0]		beq	miny, maxy, setupLN_ExHoriz0
		/*Delay*/				addi	sys1, sys1, -1877
		vsub	yH, vmin, vwidth[0]		bgtz	sys1, setupLN_ExHoriz
  EndAssign(miny, 7)
  EndAssign(maxy, 8)
		vadd	yL, vmax, vwidth[0]		/*Delay*/
		#---- サブピクセル計算 yf[1]を使用
		vmudn	xHf, yH,   _0x4000		ssv	yL[2], 2+8(outp)
		#---- DaDx = 0, DaDy = DaDe		#---- outp への出力 (Major=0x00固定)
		vadd	DaDyf, vzero, _0x0000		ssv	yM[2], 4+8(outp)
		vadd	DaDyi, vzero, _0x0000		ssv	yH[2], 6+8(outp)
							jal	setupLN_Attr
		/*Delay*/				ssv	DxDyf[0], 14+8(outp)	# DxDyL
							ssv	DxDyi[0], 12+8(outp)
		vmudm	xMi, vmin,  _0x4000		ssv	DxDyf[0], 22+8(outp)	# DxDyH
		vmadn	xMf, vzero, _0x0000		ssv	DxDyi[0], 20+8(outp)
							slv	vzero[0], 28+8(outp)	# DxDyM
							ssv	xMi[0],    8+8(outp)
							j	setupLN_Exit
							ssv	xMf[0],   10+8(outp)
		
		#--------------------------------------------------------
		#  真横ラインの作画
		#--------------------------------------------------------
setupLN_ExHoriz0:
		vsub	yH, vmin, vwidth[0]
setupLN_ExHoriz:
		vmudm	xHi, vmin,  _0x4000		xori	tile, tile, 0x80
		vmadn	xHf, vzero, _0x0000		sb	tile,      1+8(outp)
		vmudm	xMi, vmax,  _0x4000		slv	vzero[0], 20+8(outp)	# DxDyH
		vmadn	xMf, vzero, _0x0000		slv	vzero[0], 28+8(outp)	# DxDyM
		vadd	DaDef, vzero, _0x0000		ssv	yH[2], 6+8(outp)
		vadd	DaDei, vzero, _0x0000		ssv	yM[2], 4+8(outp)
		vadd	DaDyf, vzero, _0x0000		ssv	yM[2], 2+8(outp)
		vadd	DaDyi, vzero, _0x0000
  EndAssign(yH, v13)
  EndAssign(yM, v14)
  EndAssign(yL, v28)
  EndAssign(tile, 9)
  EndAssign(aDelf, v15)
  EndAssign(aDeli, v16)
  EndAssign(vH, v8)
  EndAssign(vmax, v5)
  EndAssign(vmaxx, v9)
  EndAssign(vminx, v10)
  EndAssign(vwidth, v19)
  EndAssign(scis, v12)
		#--------------------------------------------------------
		#  Attr 値の出力
		#--------------------------------------------------------
setupLN_Exit:	#---- スクリーン座標値の出力
		ssv	xHi[0], 16+8(outp)			vmov	amin[6],  _0x0001
		ssv	xHf[0], 18+8(outp)			vmov	aminf[6], _0x0000
  Assign(zminf, v5)
  Assign(zmin, v8)  
		ssv	xMi[0], 24+8(outp)			vmudn	zminf, aminf, _0x0020
		ssv	xMf[0], 26+8(outp)			vmadh	zmin,  amin,  _0x0020
  EndAssign(xMf, v26)
  EndAssign(xMi, v27)
  Assign(DzDxf, v9)
  Assign(DzDxi, v10)
  Assign(DzDef, v12)
  Assign(DzDei, v13)
		addi	outp, outp, 32+8			vmudn	DzDxf, DaDxf, _0x0020
		andi	sys0, flag, G_RDP_TRI_SHADE_MASK	vmadh	DzDxi, DaDxi, _0x0020
		/*Resv*/					vmudn	DzDef, DaDef, _0x0020
		beq	sys0, zero, setupLN_Txtr		/*Resv*/
		andi	sys0, flag, G_RDP_TRI_TXTR_MASK		/*Delay*/
		#---- カラー値の出力
		sdv	amin[0],   0(outp)
		sdv	DaDxi[0],  8(outp)
		sdv	DaDxf[0], 24(outp)
		sdv	DaDei[0], 32(outp)
		sdv	DaDyi[0], 40(outp)
		sdv	DaDef[0], 48(outp)
		sdv	DaDyf[0], 56(outp)
		addi	outp, outp, 64
setupLN_Txtr:	#---- テクスチャ値の出力
		/*Resv*/					vmadh	DzDei, DaDei, _0x0020
		beq	sys0, zero, setupLN_Zbuf		/*Resv*/
		andi	sys0, flag, G_RDP_TRI_ZBUFF_MASK	/*Delay*/
		addi	outp, outp, 64
		sdv	amin[8],   0-64(outp)
		sdv	aminf[8], 16-64(outp)
		sdv	DaDxi[8],  8-64(outp)
		sdv	DaDxf[8], 24-64(outp)
		sdv	DaDei[8], 32-64(outp)
		sdv	DaDef[8], 48-64(outp)
		sdv	DaDyi[8], 40-64(outp)
		sdv	DaDyf[8], 56-64(outp)
  EndAssign(flag, 1)
  EndAssign(DaDxf, v22)
  EndAssign(DaDxi, v23)
setupLN_Zbuf:	#---- Z バッファ値の出力
		beq	sys0, zero, OutputClose
		lhu	return, RSP_SUBMOD_LN_RETURN(zero)		
		ssv	zmin[14],   0(outp)
		addi	outp, outp, 16
		ssv	zminf[14],  2-16(outp)			vmudn	DaDyf, DaDyf, _0x0020
		ssv	DzDxi[14],  4-16(outp)			vmadh	DaDyi, DaDyi, _0x0020
		ssv	DzDxf[14],  6-16(outp)		
		ssv	DzDei[14],  8-16(outp)		
		ssv	DzDef[14], 10-16(outp)		
		ssv	DaDyi[14], 12-16(outp)
		j	OutputClose
		ssv	DaDyf[14], 14-16(outp)
  EndAssign(zmin, v8)	
  EndAssign(zminf, v5)	
  EndAssign(DzDxf, v9)	
  EndAssign(DzDxi, v10)	
  EndAssign(DzDef, v12)	
  EndAssign(DzDei, v13)	
  EndAssign(DaDyf, v24)
  EndAssign(DaDyi, v25)
		#---- サブピクセル値による xM,xH,Attr の修正処理
setupLN_Attr:	vsubc	xHf, vzero, xHf
		vsub	xHi, vzero, vzero
		vmudn	vtmp,  aminf, _0x0001
		vmadh	vtmp,  amin,  _0x0001
		vmadl	vtmp,  DaDef, xHf[1]
		vmadm	vtmp,  DaDei, xHf[1]
		vmadn	aminf, DaDef, xHi[1]
		vmadh	amin,  DaDei, xHi[1]
		vmudn	vtmp,  vmin,  _0x4000
		vmadl	vtmp,  DxDyf, xHf[1]
		vmadm	vtmp,  DxDyi, xHf[1]	sdv	aminf[0], 16+32+8(outp)
		vmadn	xHf,   DxDyf, xHi[1]	jr	return
		vmadh	xHi,   DxDyi, xHi[1]	# xi[0]
  EndAssign(vmin, v4)
  EndAssign(amin, v6)
  EndAssign(aminf, v2)
  EndAssign(DxDyf, v7)
  EndAssign(DxDyi, v11)
  EndAssign(DaDef, v17)
  EndAssign(DaDei, v18)
  EndAssign(amaxf, v3)
  EndAssign(xHf, v20)
  EndAssign(xHi, v21)
	
 #======== End of gxline_ln.s ========#