gxclip_ln.s
7 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
/*---------------------------------------------------------------------*
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 ========*/