gxlight_flxrej.s
10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
/*---------------------------------------------------------------------*
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 ========*/