gzmath.s
22.8 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
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
/*---------------------------------------------------------------------
$Id: gzmath.s,v 1.1.1.1 2002/05/02 03:29:12 blythe Exp $
File : gzmath.s
Coded by Yoshitaka Yasumoto. Jul 1, 1997.
Copyright by Nintendo, Co., Ltd. 1997.
---------------------------------------------------------------------*/
#ifndef OVERLAY_AREA
#---------------------------------------------------------------------
# case_G_MTXTRNSP
# +--------+--------+--------+--------+
# | Cmd:8 | 0 | 0 | 0 |
# +--------+--------+--------+--------+
# | 0 | 0 | 0 | Mid:8 |
# +--------+--------+--------+--------+
# Mid の 3x3 の部分を倒置する.
# 00 01 02 03 00 10 20 03
# 10 11 12 13 -> 01 11 21 13
# 20 21 22 23 02 12 22 23
# 30 31 32 33 30 31 32 33
#---------------------------------------------------------------------
case_G_MTXTRNSP:
Assign(mtx0, 1)
Assign(mtx1, 2)
Assign(vMtxi, v2)
Assign(vMtxf, v3)
lhu mtx0, RSP_MOVEMEM_TBL(gfx1)
addiu mtx1, mtx0, 2
#
# 行列のロード
# vMtxi[i00|i01|i02|i12|i10|i20|i21|i13]
# vMtxf[f00|f01|f02|f12|f10|f20|f21|f13]
#
lqv vMtxi[0], 0(mtx0) # i01,i02,i10
lsv vMtxi[6], 12(mtx0) # i12
llv vMtxi[10], 16(mtx0) # i20,i21
lqv vMtxf[0], 32(mtx0) # f01,f02,f10
lsv vMtxf[6], 44(mtx0) # f12
llv vMtxf[10], 48(mtx0) # f20,f21
#
# 行列のストア
#
slv vMtxi[8], 0(mtx1) # i10,i20
ssv vMtxi[2], 8(mtx0) # i01
slv vMtxi[4], 16(mtx0) # i02,i12
ssv vMtxi[12], 12(mtx0) # i21
slv vMtxf[8], 32(mtx1) # f10,f20
ssv vMtxf[2], 40(mtx0) # f01
slv vMtxf[4], 48(mtx0) # f02,f12
jr gfxdone
ssv vMtxf[12], 44(mtx0) # f21
EndAssign(mtx0, 1)
EndAssign(mtx1, 2)
EndAssign(vMtxi, v2)
EndAssign(vMtxf, v3)
#---------------------------------------------------------------------
# case_G_LIGHTING
# +------+-+-------------+------------+
# |LIGHT |F| Color:12 | Norm:12 |
# +------+-+-------------+------------+
# | Num:8 | DestColor:12| DestTxtr:12|
# +--------+-------------+------------+
#
# 直前の ROT_LIGHT で保存された Lptr , Lnum の値でライト計算を行なう.
# Dest の位置に r,g,b,0xff,S,T を出力する.
# F が 1 なら環境マップ用のパラメータ S,T をリニア変換し出力する.
# ただしリニア変換は TEX_GEN_LINEAR が定義されていないと組み込まれ
# ない. (7 命令必要となる)
#---------------------------------------------------------------------
case_G_LIGHTING:
Assign(color, 1)
#define norm gfx0
Assign(destColor,2)
#define destTxtr gfx1
Assign(lptr, 3)
Assign(flag, 4)
Assign(mcolor1, 5)
Assign(mcolor2, 6)
Assign(mcolor3, 7)
Assign(mcolor4, 8)
Assign(cskip, 9)
Assign(lcolor, v2)
Assign(ldir, v3)
Assign(envst, v4)
Assign(color12, v5)
Assign(color34, v6)
Assign(mater12, v7)
Assign(mater34, v8)
Assign(sumcol12, v9)
Assign(sumcol34,v10)
Assign(norm12, v11)
Assign(norm34, v12)
Assign(dotp12, v13)
Assign(dotp34, v14)
Assign(vtmpA12, v15)
Assign(vtmpA34, v16)
Assign(vtmpB12, v17)
Assign(vtmpB34, v18)
Assign(alpha, v19)
srl destColor, gfx1, 12
srl color, gfx0, 12
#ifdef TEX_GEN_LINEAR
sll flag, gfx0, 7 # もし F=1 なら flag<0
#endif
# もし DEFAULT_MATERIAL を使うなら cskip は 0 にする. 他は 16
andi sys0, color, 0xc00
srl sys0, sys0, 10
lbu cskip, RSP_LIGHT_CSKIP(sys0)
case_G_LIGHTING_Vtx:
# 法線ベクトルの取得
lw mcolor1, 0(norm)
lw mcolor2, 3(norm)
addiu norm, norm, 12
lw mcolor3, 6-12(norm)
sw mcolor1, RSPZS_VSCRATCH+ 0(zero)
lw mcolor4, 9-12(norm)
sw mcolor2, RSPZS_VSCRATCH+ 4(zero)
lw lptr, RSPZS_LPTR_SAVE(zero)
sw mcolor3, RSPZS_VSCRATCH+ 8(zero)
lpv norm12[0], oRSPZS_VSCRATCH+0(vecptr) # 法線V取得 1.2
sw mcolor4, RSPZS_VSCRATCH+12(zero)
lpv norm34[0], oRSPZS_VSCRATCH+8(vecptr) # 法線V取得 3.4
lpv ldir[0], 24(lptr) # 光線ベクトル取得
luv sumcol12[0], 0(lptr) # 環境光加算 1.2
luv sumcol34[0], 0(lptr) # 環境光加算 3.4
case_G_LIGHTING_Light:
# 法線ベクトルと光線ベクトルの内積計算
vmulf vtmpA12, norm12, ldir
vmulf vtmpA34, norm34, ldir
# 光線カラー取得 & ポインタ加算
luv lcolor[0], 8(lptr)
addi lptr, lptr, 24-0x1000
# 環境マップ計算のために内積値を保存する
# envst[--|--|s1|--|s2|--|--|--]
vadd envst, vzero, dotp12[0h] # マテリアルカラーの取得
vadd vtmpB12, vtmpA12, vtmpA12[1h] luv mater12[0], 0(color)
vadd vtmpB34, vtmpA34, vtmpA34[1h] luv mater34[0], 8(color)
# 環境マップ計算のために内積値を保存する
# envst[s4|--|s1|--|s2|--|s3|--]
vmov envst[6], dotp34[0] ldv alpha[0], 0(color) # alpha[3|7|11|15]
vmov envst[0], dotp34[4] ldv alpha[8], 8(color)
vadd dotp12, vtmpB12, vtmpA12[2h]
vadd dotp34, vtmpB34, vtmpA34[2h]
# 2cyc Stall
# 内積値に光線カラーを乗じ, ライトにおける照光値を求める.
vmulf color12, lcolor, dotp12[0h]
vmulf color34, lcolor, dotp34[0h]
# 環境マップ計算のために内積値を保存する
# envst[s4|--|s1|t1|s2|t2|s3|--]
vmov envst[3], dotp12[0]
vmov envst[5], dotp12[4]
# カラーがマイナスなら 0 に切り上げる
vge color12, color12, _0x0000
vge color34, color34, _0x0000
# 環境マップ計算のために内積値を保存する
# envst[s4|t4|s1|t1|s2|t2|s3|t3]
vmov envst[7], dotp34[0]
vmov envst[1], dotp34[4]
# 光線ベクトル取得
lpv ldir[0], 24(lptr)
# color の累計値を求める.
vadd sumcol12, sumcol12, color12
bgtz lptr, case_G_LIGHTING_Light
vadd sumcol34, sumcol34, color34
addiu destTxtr, destTxtr, 16
#ifdef TEX_GEN_LINEAR
bgez flag, case_G_LIGHTING_Skip
#endif
# 光源のカラー値にマテリアルカラー値を掛ける 1.2
vmulf sumcol12, sumcol12, mater12 # In delay slot
#ifdef TEX_GEN_LINEAR
# S,T のリニア変換を行なう
vmulf lcolor, envst, envst
vmulf lcolor, lcolor, envst
vmulf vtmp, lcolor, _ArcSin0
vmacf vtmp, lcolor, _ArcSin1
vmacf envst, envst, _ArcSin2
case_G_LIGHTING_Skip:
#endif
# 環境マップパラメータの正規化(0-32 の値にする)[1]
vaddc envst, envst, _0x8000
add color, color, cskip
suv sumcol12[0], 0(destColor) # Color1,2
# 光源のカラー値にマテリアルカラー値を掛ける 3.4
vmulf sumcol34, sumcol34, mater34
sbv alpha[3], 3(destColor)
# 環境マップパラメータの正規化(0-32 の値にする)[2]
vmudl envst, envst, _0x0400
sbv alpha[7], 7(destColor)
addi destColor, destColor, -0x2000+8
bltz destColor, case_G_LIGHTING_Done
sdv envst[4], 0-16(destTxtr) # Txtr 1,2
suv sumcol34[0], 0(destColor) # Color3,4
sbv alpha[11], 3(destColor)
sbv alpha[15], 7(destColor)
addi destColor, destColor, -0x2000+8
bgez destColor, case_G_LIGHTING_Vtx
sdv envst[12], 8-16(destTxtr) # Txtr 3,4
case_G_LIGHTING_Done:
jr gfxdone
.symbol case_G_MULT_MPMTX_Done, case_G_LIGHTING_Done
.symbol case_G_INTRPLT_Done, case_G_LIGHTING_Done
EndAssign(color, 1)
#undef norm
EndAssign(destColor,2)
#undef destTxtr
EndAssign(lptr, 3)
EndAssign(flag, 4)
EndAssign(mcolor1, 5)
EndAssign(mcolor2, 6)
EndAssign(mcolor3, 7)
EndAssign(mcolor4, 8)
EndAssign(cskip, 9)
EndAssign(lcolor, v2)
EndAssign(ldir, v3)
EndAssign(envst, v4)
EndAssign(color12, v5)
EndAssign(color34, v6)
EndAssign(mater12, v7)
EndAssign(mater34, v8)
EndAssign(sumcol12, v9)
EndAssign(sumcol34,v10)
EndAssign(norm12, v11)
EndAssign(norm34, v12)
EndAssign(dotp12, v13)
EndAssign(dotp34, v14)
EndAssign(vtmpA12, v15)
EndAssign(vtmpA34, v16)
EndAssign(vtmpB12, v17)
EndAssign(vtmpB34, v18)
EndAssign(alpha, v19)
#---------------------------------------------------------------------
# case_G_MULT_MPMTX
#
# +--------+--------+--------+--------+
# | Cmd:8 | 0 | Mid:8 |
# +--------+--------+----+---+--------+
# | Num:8 | Src:12 | Dest:12 |
# +--------+-------------+------------+
#
# User Area の Src の位置におけるデータを 16bit の x,y,z 値とみなし
# Mid で指定した 4x4 行列をかけ, W で割り, ViewPort 変換を行なう.
# (Num+1) 個の頂点が処理される. (Num+1) が 4 以上であることが望ましい.
# (Num+1) が 3 以下であった場合 領域(Dest ... Dest+63)は保存されない.
#---------------------------------------------------------------------
FixedAssign(vmtx0i, v2)
FixedAssign(vmtx1i, v3)
FixedAssign(vmtx2i, v4)
FixedAssign(vmtx3i, v5)
FixedAssign(vmtx0f, v6)
FixedAssign(vmtx1f, v7)
FixedAssign(vmtx2f, v8)
FixedAssign(vmtx3f, v9)
LoadMatrix:
#------ マトリクスの取得 ------
lhu sys0, RSP_MOVEMEM_TBL(gfx0)
lqv vmtx2f[0], 48(sys0)
lqv vmtx2i[0], 16(sys0)
lqv vmtx0f[0], 32(sys0)
lqv vmtx0i[0], 0(sys0)
vadd vmtx3f, vmtx2f, _0x0000
vadd vmtx3i, vmtx2i, _0x0000 ldv vmtx3f[0], 56(sys0)
vadd vmtx1f, vmtx0f, _0x0000 ldv vmtx3i[0], 24(sys0)
vadd vmtx1i, vmtx0i, _0x0000 ldv vmtx1f[0], 40(sys0)
ldv vmtx1i[0], 8(sys0)
ldv vmtx2f[8], 48(sys0)
ldv vmtx2i[8], 16(sys0)
ldv vmtx0f[8], 32(sys0)
jr return
ldv vmtx0i[8], 0(sys0)
Assign(pNorm, v10)
Assign(pNormSi, v11)
Assign(pNormSf, v12)
Assign(pNormT, v13)
Assign(pNormX2, v14)
Assign(fctNormT,v15)
Assign(pNormS, v16)
Assign(num, 1)
Assign(src, 2)
#define dest gfx1
Assign(dskip, 3)
Assign(invW12, v22)
Assign(invW34, v23)
Assign(vmasky, v28)
case_G_MULT_MPMTX: #------ Y 座標マスク値 vmasky に
#------ [3|7] への代入用フラグの設定 ------ # [0xffff|0xfffc|x|x|0xffff|0xfffc|x|x] を代入
_li (sys0, 0x77) vsub vmasky, vzero, _0x0001
#------ ViewPort および PerspNorm の取得 ------
llv pNorm[0], RSP_STATEP_PERSPNORM(zero) vmov vmasky[1], _0xfffc
ctc2 sys0, $vcc # 並列実行不可
ldv pNormS[0], RSP_STATEP_VIEWPORT_SC(zero) vmov vmasky[5], _0xfffc
#------ invW12[2|3,6|7],invW34[2|3,6|7]に
# 1/32 を代入して FOG 計算に使用する
ldv pNormS[8], RSP_STATEP_VIEWPORT_SC(zero) vmrg invW12, vzero, _0x0400
ldv pNormT[0], RSP_STATEP_VIEWPORT_TX(zero) vmrg invW34, vzero, _0x0400
vadd pNormX2, pNorm, pNorm # 2 倍
jal LoadMatrix
ldv pNormT[8], RSP_STATEP_VIEWPORT_TX(zero)
#------ src アドレスの取得 ------ #------ Persp Normalize 係数の乗算 ------
srl src, gfx1, 12 vmudm pNormSi, pNormS, pNormX2[1]
#------ num の取得 ------
srl num, gfx1, 24 vmadn pNormSf, vconst, _0x0000
#------ fctNormT に [1|1|1|64|1|1|1|64] を代入
addi num, num, 3 vmrg fctNormT, vone, _0x0040
#------ Dskip の初期化 ------
_li (dskip, 0) /*V*/
EndAssign(pNormX2, v14)
Assign(vsrc, v14)
#------ 入力値取得 ------ #------ Norm の混合 ------
ldv vsrc[0], 0(src) vmrg pNormSi, pNormSi, pNormS[3h]
addiu src, src, 6 vmrg pNormSf, pNormSf, _0x0000
ldv vsrc[8], 0(src) /*V*/
EndAssign(pNormS, v16)
case_G_MULT_MPMTX_Loop_0:
addiu src, src, 6 /*V*/
Assign(flag1, 4)
Assign(flag2, 5)
Assign(flag3, 6)
Assign(flag4, 7)
Assign(vdest12i, v16)
Assign(vdest12f, v17)
Assign(vdest34i, v18)
Assign(vdest34f, v19)
Assign(Wi, v20)
Assign(Wf, v21)
Assign(vout12i, v24)
Assign(vout12f, v25)
Assign(vout34i, v26)
Assign(vout34f, v27)
case_G_MULT_MPMTX_Loop:
#------ (1,2) 行列の乗算処理 ------
vmudn vtmp, vmtx3f, _0x0001 slv vout12f[0], 0+16*0(dest)
vmadh vtmp, vmtx3i, _0x0001 sbv vout12i[6], 13+16*0(dest)
vmadn vtmp, vmtx1f, vsrc[1h] bltz num, case_G_MULT_MPMTX_Done
vmadh vtmp, vmtx1i, vsrc[1h] # 遅延
vmadn vtmp, vmtx2f, vsrc[2h] sdv vdest12i[8], 8+16*1(dest)
vmadh vtmp, vmtx2i, vsrc[2h] sh flag2, 12+16*1(dest)
vmadn vdest12f, vmtx0f, vsrc[0h] slv invW12 [8], 4+16*1(dest)
vmadh vdest12i, vmtx0i, vsrc[0h] slv vout12f[8], 0+16*1(dest)
#------ (3,4) 座標値(x,y,z) の W での除算 ------
vmudl vtmp, vdest34f, invW34[1q] sbv vout12i[14], 13+16*1(dest)
vmadm vtmp, vdest34i, invW34[1q] beq num, zero, case_G_MULT_MPMTX_Done
vmadn vout34f, vdest34f, Wi[0q] # 遅延
vmadh vout34i, vdest34i, Wi[0q] addi num, num, -2
#------ (1,2) n/W の分母への Normal 係数の乗算 ------ #------ 座標ソース読み込み ------
vmudl vtmp, vdest12f, pNorm[1] ldv vsrc[0], 0(src)
vmadm Wi, vdest12i, pNorm[1] addiu src, src, 6
vmadn Wf, vconst, _0x0000 ldv vsrc[8], 0(src)
#------ (3,4) n/W の分子への Normal 係数の乗算 ------
# fctNorm は W の係数のみ 64 となっている.(他は 1)
vmudh vtmp, pNormT, fctNormT addiu src, src, 6
#------ Clip フラグ取得
vmadl vtmp, pNormSf, vout34f andi flag4, flag3, 0x7070
vmadm vtmp, pNormSi, vout34f sll sys0, flag4, 4
vmadn vout34f, pNormSf, vout34i or flag4, flag4, sys0
vmadh vout34i, pNormSi, vout34i andi flag3, flag3, 0x0707
#------ (1,2) W の逆数の計算 (1) ------
# invW12[2|3,6|7] には 0x00010001 が代入されて
# 掛けても変化がない (W の値を FOG 用に使用する為)
vrcph vtmp[0], Wi[3] srl sys0, flag3, 4
vrcpl invW12[1], Wf[3] or flag3, flag3, sys0
vrcph invW12[0], Wi[7] /*S*/
vrcpl invW12[5], Wf[7] /*S*/
vrcph invW12[4], _0x0000 /*S*/
#------ (3,4) y 座標サブピクセルのマスク ------
vand vout34f, vout34i, vmasky /*S*/
#------ (3,4) Fog パラメータ正規化 ------
# (0x80-0x7f => 0x00-0xff) #------ 結果書き込み ------
vxor vout34i, vout34i, _0x8000 sdv vdest34i[0], 8+16*2(dest)
#------ (1,2) 画面外かどうかのフラグの取得 ------
vch vtmp, vdest12i, vdest12i[3h] sb flag3, 12+16*2(dest)
vcl vtmp, vdest12f, vdest12f[3h] slv invW34 [0], 4+16*2(dest)
cfc2 flag1, $vcc
#------ (1,2) W が負のときに 1/W を最大値にする ------
# 1/W の補正値(Wi)は X/W,Y/W の計算のみに使用する
vge vtmp, invW12, _0x0000 slv vout34f[0], 0+16*2(dest)
vmrg Wi, invW12, _0x7fff sbv vout34i[6], 13+16*2(dest)
#------ (3,4) 行列の乗算処理 ------
vmudn vtmp, vmtx3f, _0x0001 bltz num, case_G_MULT_MPMTX_Done
vmadh vtmp, vmtx3i, _0x0001 # 遅延
vmadn vtmp, vmtx1f, vsrc[1h] sdv vdest34i[8], 8+16*3(dest)
vmadh vtmp, vmtx1i, vsrc[1h] sh flag4, 12+16*3(dest)
vmadn vtmp, vmtx2f, vsrc[2h] slv invW34 [8], 4+16*3(dest)
vmadh vtmp, vmtx2i, vsrc[2h] slv vout34f[8], 0+16*3(dest)
vmadn vdest34f, vmtx0f, vsrc[0h] sbv vout34i[14], 13+16*3(dest)
vmadh vdest34i, vmtx0i, vsrc[0h] beq num, zero, case_G_MULT_MPMTX_Done
#------ (1,2) 座標値(x,y,z) の W での除算 ------
vmudl vtmp, vdest12f, invW12[1q] # 遅延
vmadm vtmp, vdest12i, invW12[1q] add dest, dest, dskip
vmadn vout12f, vdest12f, Wi[0q] _li (dskip, 16*4)
vmadh vout12i, vdest12i, Wi[0q] addi num, num, -2
#------ (3,4) n/W の分母への Normal 係数の乗算 ------ #------ 座標ソース読み込み ------
vmudl vtmp, vdest34f, pNorm[1] ldv vsrc[0], 0(src)
vmadm Wi, vdest34i, pNorm[1] addiu src, src, 6
vmadn Wf, vconst, _0x0000 ldv vsrc[8], 0(src)
#------ (1,2) n/W の分子への Normal 係数の乗算 ------
vmudh vtmp, pNormT, fctNormT /*S*/
#------ Clip フラグ取得
vmadl vtmp, pNormSf, vout12f andi flag2, flag1, 0x7070
vmadm vtmp, pNormSi, vout12f sll sys0, flag2, 4
vmadn vout12f, pNormSf, vout12i or flag2, flag2, sys0
vmadh vout12i, pNormSi, vout12i andi flag1, flag1, 0x0707
#------ (3,4) W の逆数の計算 (1) ------
# invW12[2|3,6|7] には 0x00010001 が代入されて
# 掛けても変化がない (W の値を FOG 用に使用する為)
vrcph vtmp[0], Wi[3] srl sys0, flag1, 4
vrcpl invW34[1], Wf[3] or flag1, flag1, sys0
vrcph invW34[0], Wi[7] /*S*/
vrcpl invW34[5], Wf[7] /*S*/
vrcph invW34[4], _0x0000 /*S*/
#------ (1,2) y 座標サブピクセルのマスク ------
vand vout12f, vout12i, vmasky /*S*/
#------ (1,2) Fog パラメータ正規化 ------
# (0x80-0x7f => 0x00->0xff) #------ 結果書き込み ------
vxor vout12i, vout12i, _0x8000 sdv vdest12i[0], 8+16*0(dest)
#------ (3,4) 画面外かどうかのフラグの取得 ----
vch vtmp, vdest34i, vdest34i[3h] sb flag1, 12+16*0(dest)
vcl vtmp, vdest34f, vdest34f[3h] slv invW12 [0], 4+16*0(dest)
cfc2 flag3, $vcc # 並列不可
#------ (3,4) W が負のときに 1/W を最大値にする ------
# 1/W の補正値(Wi)は X/W,Y/W の計算のみに使用する
vge vtmp, invW34, _0x0000 j case_G_MULT_MPMTX_Loop_0
vmrg Wi, invW34, _0x7fff # 遅延
EndAssign(num, 1)
EndAssign(src, 2)
#undef dest
EndAssign(dskip, 3)
EndAssign(flag1, 4)
EndAssign(flag2, 5)
EndAssign(flag3, 6)
EndAssign(flag4, 7)
EndAssign(vmtx0i, v2)
EndAssign(vmtx1i, v3)
EndAssign(vmtx2i, v4)
EndAssign(vmtx3i, v5)
EndAssign(vmtx0f, v6)
EndAssign(vmtx1f, v7)
EndAssign(vmtx2f, v8)
EndAssign(vmtx3f, v9)
EndAssign(pNorm, v10)
EndAssign(pNormSi, v11)
EndAssign(pNormSf, v12)
EndAssign(pNormT, v13)
EndAssign(vsrc, v14)
EndAssign(fctNormT, v15)
EndAssign(vdest12i, v16)
EndAssign(vdest12f, v17)
EndAssign(vdest34i, v18)
EndAssign(vdest34f, v19)
EndAssign(Wi, v20)
EndAssign(Wf, v21)
EndAssign(invW12, v22)
EndAssign(invW34, v23)
EndAssign(vout12i, v24)
EndAssign(vout12f, v25)
EndAssign(vout34i, v26)
EndAssign(vout34f, v27)
EndAssign(vmasky, v28)
#endif
#---------------------------------------------------------------------
# case_G_INTRPLT
#
# +--------+--------+--------+--------+
# | Cmd:8 | Type:8 | Factor:16 |
# +--------+--------+----+---+--------+
# | Num:8 | Src1:12 | Src2:12 |
# +--------+--------+----+---+--------+
#
# Type 補間するデータの型 (0:s16, 2:s8, 4:u8)
# Factor 混ぜ合わせ係数 (0-0x7fff) (u0.15)
# Num データの数/8-1 (データの数は 8 の倍数)
# Src1 補間するデータ 1 へのポインタ/出力先へのポインタ
# Src2 補間するデータ 2 へのポインタ
#
# 以下の計算式で補間を行なう.
# (*Src1) = Factor * (*Src1) + (0x7fff-Factor) * (*Src2)
#---------------------------------------------------------------------
Assign(fact, v2)
Assign(ifact, v3)
Assign(vsrc1, v4)
Assign(vsrc2, v5)
Assign(c1p, 1)
Assign(goNext, 2)
#define c2p gfx1
#ifndef OVERLAY_AREA
case_G_INTERPOLATE:
srl sys0, gfx0, 16
lhu goNext, -RSP_INTRPLT_OFFSET(sys0)
mtc2 gfx0, fact[0]
srl c1p, gfx1, 12
addi sys0, goNext, 4
jr sys0 # Jump to Load inst.
vxor ifact, fact, _0x7fff
case_G_INTRPLT_S16_Sub:
sqv vsrc1[0],-16(c1p)
lqv vsrc1[0], 0(c1p)
lqv vsrc2[0], 0(c2p)
addi c1p, c1p, 8
addi c2p, c2p, 8
case_G_INTRPLT_Loop:
bltz c1p, case_G_INTRPLT_Done
vmulf vtmp, vsrc1, fact[0]
vmacf vsrc1, vsrc2, ifact[0]
addi c1p, c1p, 8-0x1000
jr goNext
addi c2p, c2p, 8
#else
case_G_INTRPLT_S8_Sub:
spv vsrc1[0],-8(c1p)
lpv vsrc1[0], 0(c1p)
j case_G_INTRPLT_Loop
lpv vsrc2[0], 0(c2p)
case_G_INTRPLT_U8_Sub:
suv vsrc1[0],-8(c1p)
luv vsrc1[0], 0(c1p)
j case_G_INTRPLT_Loop
luv vsrc2[0], 0(c2p)
#endif
EndAssign(fact, v2)
EndAssign(ifact, v3)
EndAssign(vsrc1, v4)
EndAssign(vsrc2, v5)
EndAssign(c1p, 1)
EndAssign(goNext, 2)
#undef c2p
#ifdef OVERLAY_AREA
#---------------------------------------------------------------------
# case_G_XFMLIGHT
# +--------+--------+--------+--------+
# | Cmd:8 | 0 | Mid:8 |
# +--------+----+---+----+---+--------+
# | 0 | Lnum:8 | Lptr:12 |
# +--------+----+---+----+---+--------+
# ライトベクトルの回転処理を行なう.
# Lnum+1 個処理する. Lptr で指定されているのは環境光のデータ位置.
# Lnum と Lptr は保存され, G_SET_LIGHT で参照される.
#
# ライトデータは以下となる
# 環境光 8 Bytes
# 拡散光 24 Bytes (1 つにつき)
# 環境マップ用
# パラメータ 48 Bytes
#
# ライト構造体
# typedef struct {
# u8 r, g, b, a;
# u8 r, g, b, a;
# s8 lx, ly, lz, la;
# u32 padding;
# u32 work0, work1;
# }
#
# ライト構造体 Lptr から (lx, ly, lz) の 3 つを取りだし,
# work0, work1 へ変換後の値を (nx,ny,nz,-,nx,ny,nz,-) と返す.
#---------------------------------------------------------------------
case_G_XFMLIGHT:
FixedAssign(vmtx0i, v2)
FixedAssign(vmtx1i, v3)
FixedAssign(vmtx2i, v4)
FixedAssign(vmtx3i, v5)
FixedAssign(vmtx0f, v6)
FixedAssign(vmtx1f, v7)
FixedAssign(vmtx2f, v8)
FixedAssign(vmtx3f, v9)
Assign(vsrc, v10)
Assign(vdesti, v11)
Assign(vdestf, v12)
Assign(invsqi, v13)
Assign(invsqf, v14)
Assign(vtmpi, v15)
Assign(vtmpf, v16)
jal LoadMatrix
sw gfx1, RSPZS_LPTR_SAVE(zero)
VectXfmLoop:
lpv vsrc[0], 8+8(gfx1)
vmudn vtmp, vmtx0f, vsrc[0]
vmadh vtmp, vmtx0i, vsrc[0]
vmadn vtmp, vmtx1f, vsrc[1]
vmadh vtmp, vmtx1i, vsrc[1]
vmadn vtmp, vmtx2f, vsrc[2]
vmadh vtmp, vmtx2i, vsrc[2]
vsar vdestf, vdestf, vdestf[1]
vsar vdesti, vdesti, vdestf[0]
vmudl vtmp, vdestf, vdestf
vmadm vtmp, vdesti, vdestf
vmadn invsqf, vdestf, vdesti
vmadh invsqi, vdesti, vdesti
vaddc vtmpf, invsqf, invsqf[1]
vadd vtmpi, invsqi, invsqi[1]
vaddc invsqf, vtmpf, invsqf[2]
vadd invsqi, vtmpi, invsqi[2]
vrsqh vtmp [0], invsqi[0]
vrsql invsqf[0], invsqf[0]
vrsqh invsqi[0], _0x0000
vmudl vtmp, invsqf, _0x0200
vmadm invsqi, invsqi, _0x0200
vmadn invsqf, vzero, _0x0000
vmudl vtmp, vdestf, invsqf[0]
vmadm vtmp, vdesti, invsqf[0]
vmadn vdestf, vdestf, invsqi[0]
vmadh vdesti, vdesti, invsqi[0]
vmudn vdestf, vdestf, _0x7fff
vmadh vdesti, vdesti, _0x7fff
spv vdesti[0], 16+8(gfx1)
lw sys0, 16+8(gfx1)
addi gfx1, gfx1, 24-0x1000
bgez gfx1, VectXfmLoop
sw sys0, 20+8-24(gfx1)
jr gfxdone
EndAssign(vmtx0i, v2)
EndAssign(vmtx1i, v3)
EndAssign(vmtx2i, v4)
EndAssign(vmtx3i, v5)
EndAssign(vmtx0f, v6)
EndAssign(vmtx1f, v7)
EndAssign(vmtx2f, v8)
EndAssign(vmtx3f, v9)
EndAssign(vsrc, v10)
EndAssign(vdesti, v11)
EndAssign(vdestf, v12)
EndAssign(invsqi, v13)
EndAssign(invsqf, v14)
EndAssign(vtmpi, v15)
EndAssign(vtmpf, v16)
#---------------------------------------------------------------------
# case_G_MTXCAT
# +--------+--------+--------+--------+
# | Cmd:8 | 0 | 0 | MidS:8 |
# +--------+--------+--------+--------+
# | 0 | MidT:8 | 0 | MidD:8 |
# +--------+--------+--------+--------+
# MidS の行列と MidT の行列を乗じて, MidD に保存する.
#---------------------------------------------------------------------
Assign(MtxS, 1)
Assign(MtxT, 2)
Assign(MtxD, 3)
Assign(eMtxD, 4)
Assign(eMtxS, 5)
Assign(vMtxSi, v2)
Assign(vMtxSf, v3)
Assign(vMtxTi, v4)
Assign(vMtxTf, v5)
Assign(vMtxDi, v6)
Assign(vMtxDf, v7)
case_G_MTXCAT:
lhu MtxS, RSP_MOVEMEM_TBL(gfx0)
lhu MtxD, RSP_MOVEMEM_TBL(gfx1)
srl sys0, gfx1, 16
lhu MtxT, RSP_MOVEMEM_TBL(sys0)
addi eMtxD, MtxD, 16
case_G_MTXCAT_loop1:
vmudh vtmp, vconst, _0x0000
addi eMtxS, MtxS, 8
case_G_MTXCAT_loop2:
ldv vMtxTf[0], 32(MtxT)
ldv vMtxTf[8], 32(MtxT)
lqv vMtxSf[0], 32(MtxS)
ldv vMtxTi[0], 0(MtxT)
ldv vMtxTi[8], 0(MtxT)
lqv vMtxSi[0], 0(MtxS)
vmadl vtmp, vMtxTf, vMtxSf[0h]
addi MtxS, MtxS, 2
vmadm vtmp, vMtxTi, vMtxSf[0h]
addi MtxT, MtxT, 8
vmadn vMtxDf, vMtxTf, vMtxSi[0h]
bne MtxS, eMtxS, case_G_MTXCAT_loop2
vmadh vMtxDi, vMtxTi, vMtxSi[0h]
addi MtxT, MtxT, -32
addi MtxS, MtxS, 8
sqv vMtxDf[0], 32(MtxD)
sqv vMtxDi[0], 0(MtxD)
bne MtxD, eMtxD, case_G_MTXCAT_loop1
addi MtxD, MtxD, 16
jr gfxdone
nop
EndAssign(MtxS, 1)
EndAssign(MtxT, 2)
EndAssign(MtxD, 3)
EndAssign(eMtxD, 4)
EndAssign(eMtxS, 5)
EndAssign(vMtxSi, v2)
EndAssign(vMtxSf, v3)
EndAssign(vMtxTi, v4)
EndAssign(vMtxTf, v5)
EndAssign(vMtxDi, v6)
EndAssign(vMtxDf, v7)
#endif
/*======== End of gzmath.s ========*/