gs2rect.s
17.5 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
/*---------------------------------------------------------------------
Copyright (C) 1997, Nintendo.
File gs2rect.s
Coded by Yoshitaka Yasumoto. Mar 4, 1997.
Modified by
Comments
$Id: gs2rect.s,v 1.2 2002/05/03 07:22:50 blythe Exp $
---------------------------------------------------------------------*/
#!Reserved (0,11,12,17,18,19,20,23,24,25,26,27,30,31)
#!Reserved (v0,v1,v28,v29,v30,v31)
#----------------------------------------------------------------------------
# case_G_OBJ_RECT:
# case_G_OBJ_RECT_R:
# 矩形 OBJECT の作画
# RECT と RECT_R の区別は gfx0 の符号で行なう.
# gfx > 0 なら RECT, gfx < 0 なら RECT_R
#----------------------------------------------------------------------------
case_G_OBJ_RECT:
#---------------------------------------------------------------------
# uObjSprite データのアドレスを物理アドレスに変換し,
# DMA 転送をかける.
#---------------------------------------------------------------------
AssignForDMAproc
jal AdrsFixup
_li (dma_len, 23) # dram_adrs は AdrsFixup で設定される
jal DMAread
case_G_OBJ_RECT_1:
_li (dmem_adrs, RSP_INPUT_SPRITE) # 64bit alignment
EndAssignForDMAproc
#---------------------------------------------------------------------
# DMA 転送終了を待ち. その間にパラメータのロードを行なう.
# 転送終了後 Object のジオメトリデータおよびイメージデータを取得.
#
# sprite [objX|scaleX|imageS|imageW| objY|scaleY|imageT|imageH]
#---------------------------------------------------------------------
FixedAssign(sprite, v2) # objX,sclX,imgS,imgW, objY,sclY,imgT,imgH
FixedAssign(rsmode, v3) # RenderMode AA/BLP パラメータ
FixedAssign(shrink, v4) # RenderMode Shrink パラメータ
FixedAssign(sptr, 20) # uObjSprite へのポインタを設定 = dmem_adrs
Assign(spriteXY, v5) # objXY 修正値
Assign(spriteXYf, v6)
lhu sys0, RSPOBJ_RENDERP_SMODE(zero)
ldv shrink[0], oRSPOBJ_SHRINKPARAM(vecptr) # Shrink パラメータ
jal DMAwait
ldv rsmode[0], 0(sys0) # AA/BLP パラメータ
case_G_OBJ_RECT_Txtr: # LoadTxtr との複合命令の飛び先
bltz gfx0, case_G_OBJ_RECT_R_Fix
lqv sprite[0], RSP_SPR_OBJX(sptr)
#---------------------------------------------------------------------
# AA/Bilerp に伴う座標シフトの処理
# サブピクセル切捨ておよび座標値の加算
#---------------------------------------------------------------------
vadd spriteXY, sprite, shrink[iSHRINK_R_OBJXY] # [0|4]
vand spriteXY, spriteXY, rsmode[iCUT_SUBPIX] # [0|4]
vand spriteXYf, vzero, _0x0000
case_G_OBJ_RECT_R_Ret:
#---------------------------------------------------------------------
# スプライトデータを各モードに応じて修正する
#---------------------------------------------------------------------
Assign(spriteST, v7) # imgST 修正値
Assign(spriteWH, v8) # imgWH 修正値
# Shrink の処理
vsub spriteWH, sprite, shrink[iSHRINK_IMGWH] # [2|6]
vadd spriteST, vzero, shrink[iSHRINK_IMGST] # [0-7]
EndAssign(shrink, v4)
#---------------------------------------------------------------------
# Object の幅 高さを計算する.
# objW = (s32)imgW * 128 / sp->s.scaleX;
# objH = (s32)imgH * 128 / sp->s.scaleY;
# 結果は objSZ[3], objSZ[7] に代入される.
#---------------------------------------------------------------------
#-------------------------------------------------------------
# scale[XY] 値の逆数を計算する
# 1/(s5.10) = (s10.21)
#
Assign(iscalei, v4) # 1/scaleX, 1/scaleY
Assign(iscalef, v9) # 1/scaleX, 1/scaleY
/*Delay 3*/ vrcp iscalef[0], sprite[1]
vrcph iscalei[0], vtmp[0]
vrcp iscalef[4], sprite[5]
vrcph iscalei[4], vtmp[0]
#-------------------------------------------------------------
# vrcp 命令では 1 の逆数が 1 にならないので値の補正をする
#
# 0x00010000 の逆数が 0x0001ffff となるので
# High 部分を Low に加算してやる
# 形としては 0x0001.0001 を乗ずることになる.
#
vaddc iscalef, iscalef, iscalei
vadd iscalei, iscalei, _0x0000
#-------------------------------------------------------------
# image[WH] / scale[XY] を計算する
#
# imageWH(u11.5)->(s18.13) に変換後
# (s18.13)*(s10.21) = (s29.34) = (s13.18)
#
Assign(objSZi, v10)
Assign(objSZf, v11)
vmudn objSZf, spriteWH, _0x0100
vmadh objSZi, vzero, _0x0000 # [2|6]
/*Delay 2*/ vmudl vtmp, objSZf, iscalef[0h]
vmadm vtmp, objSZi, iscalef[0h]
vmadn objSZf, objSZf, iscalei[0h]
vmadh objSZi, objSZi, iscalei[0h] # [2|6]
EndAssign(iscalei, v4) # 1/scaleX, 1/scaleY
EndAssign(iscalef, v9) # 1/scaleX, 1/scaleY
#---------------------------------------------------------------------
# テクスチャ反転処理
#
# if (spriteDrawMode & G_OBJRM_TXTRWINDOW){
# /* 反転処理として MIRROR イメージでなく本体を逆方向から参照する */
# if (sp->s.imageFlags & G_OBJ_FLAG_FLIPS){
# imgS = imgS + imgW - 1; scaleX = - scaleX;
# }
# if (sp->s.imageFlags & G_OBJ_FLAG_FLIPT){
# imgT = imgT + imgH - 1; scaleY = - scaleY;
# }
# } else {
# /* S 反転, T 反転処理 (MIRROR イメージを参照する) */
# if (sp->s.imageFlags & G_OBJ_FLAG_FLIPS){
# imgS = - imgS - imgW + 1;
# }
# if (sp->s.imageFlags & G_OBJ_FLAG_FLIPT){
# imgT = - imgT - imgH + 1;
# }
# }
#---------------------------------------------------------------------
Assign(twindow, v4)
Assign(spriteSTrv, v9)
Assign(spriteSCrv, v12)
Assign(spriteSC, v13)
lhu sys0, RSPOBJ_RENDERP_TWINDOW(zero)
ldv twindow[0], 0(sys0)
vadd spriteSTrv, spriteST, spriteWH[2h] # [2|6]
vmadn spriteSTrv, vone, _0xffff
vmudn spriteSTrv, spriteSTrv, twindow[iTWIN_FLIPST] # [2|6]
vmudn spriteSCrv, sprite, twindow[iTWIN_FLIPSC] # [1|5]
lbu sys0, RSP_SPR_IMGFLAGS(sptr) # S,T Flip 処理
andi sys0, sys0, 0x11
addiu sys0, sys0, 0x77
ctc2 sys0, $vcc
vmrg spriteST, spriteST, spriteSTrv # [2|6]
vmrg spriteSC, sprite, spriteSCrv # [1|5]
EndAssign(sprite, v2)
EndAssign(spriteSTrv, v9)
EndAssign(spriteSCrv, v12)
EndAssign(spriteWH, v8)
#---------------------------------------------------------------------
# テクスチャパラメータの微調整
#
# /* テクスチャをずらす処理 (bilerp 時) */
# imgS += spriteTxtrShiftB;
# imgT += spriteTxtrShiftB;
#---------------------------------------------------------------------
#-------------------------------------------------------------
# テクスチャをずらす処理 (bilerp 時)
#
vadd spriteST, spriteST, rsmode[iR_ADD_IMGST] # [2|6]
#---------------------------------------------------------------------
# OBJ 右下座標計算
#
# /* OBJ の座標計算 */
# objXR = objXL + objW;
# objYD = objYU + objH;
#---------------------------------------------------------------------
Assign(spriteXY2, v2)
vaddc vtmp, spriteXYf, objSZf[2h] # [0|4]
vadd spriteXY2, spriteXY, objSZi[2h] # [0|4]
EndAssign(objSZi, v10)
EndAssign(objSZf, v11)
#---------------------------------------------------------------------
# シザーボックスでのクリップ
#
# XL,YL,XH,YH で矩形領域をクリップする
# XL,YL の場合はさらに S,T 座標の調整を行なう必要がある
#---------------------------------------------------------------------
Assign(scissor, v8)
Assign(dXY, v9)
Assign(dST, v10)
Assign(dSTf, v11)
Assign(check, 1)
#ifdef UCODE_S2DEX2
llv scissor[0], oRSP_SCISSOR_XL(vecptr)
llv scissor[8], oRSP_SCISSOR_YL(vecptr)
#else
llv scissor[0], RSP_STATEP_SCISSOR_XL(zero)
llv scissor[8], RSP_STATEP_SCISSOR_YL(zero)
#endif
vlt spriteXY2, spriteXY2, scissor[1h] # XH,YH でのクリップ
vsub dXY, spriteXY, scissor[0h] # クリップエリアの差分
vge spriteXY, spriteXY, scissor[0h] # XL,YL でのクリップ
vmrg dXY, vzero, dXY # クリップ無なら差分=0
vge vtmp, spriteXY, spriteXY2 # 座標比較
cfc2 check, $vcc # [0|4]
andi check, check, 0x11
bne check, zero, GfxDone # 描画領域無しなら終了
#---------------------------------------------------------------------
# S,T のシフト量を計算しそれぞれ加算する
# dXY*scaleXY = (s13.2)*(s5.10) = (s19.12) -> (s10.5)
#---------------------------------------------------------------------
vmudh vtmp, dXY, spriteSC[1h]
vsar dSTf, dSTf, dSTf[1] # [0|4]
vsar dST, dST, dST [0]
vmudl vtmp, dSTf, _0xfe00
vmadm vtmp, dST, _0xfe00
vmadn dSTf, dSTf, _0xffff
vmadn spriteST, vone, spriteST[2h] # [0|4]
EndAssign(scissor, v8)
EndAssign(dXY, v9)
EndAssign(dST, v10)
EndAssign(dSTf, v11)
EndAssign(check, 1)
#---------------------------------------------------------------------
# テクスチャパラメータの微調整
#
# /* サブテクセルの分, テクスチャを T 方向にシフトさせる */
# if (spriteDrawMode & G_OBJRM_BILERP){
# imgS -= (objXL & 3) * scaleX / 128;
# imgT -= (objYU & 3) * scaleY / 128;
# }
#---------------------------------------------------------------------
#-------------------------------------------------------------
# S,T のシフト量を計算しそれぞれ加算する
# (objXL & 3)*scaleX = (s0.11)*(s5.10) = (ss5.21) -> (s6.5)
# (objYU & 3)*scaleY = (s0.11)*(s5.10) = (ss5.21) -> (s6.5)
#
Assign(txtrf, v8)
vand txtrf, spriteXY, rsmode[iGET_SUBPIX] # [0|4]
vmudh txtrf, txtrf, vconst1[3h] # 0x0200(s0.2)->(s0.11)
vmudm txtrf, spriteSC, txtrf[0h] # [1|5]
vsub spriteST, spriteST, txtrf[1h]
EndAssign(txtrf, v8)
EndAssign(rsmode, v3)
#---------------------------------------------------------------------
# 数値の小数位置合わせ
#---------------------------------------------------------------------
Assign(XL, 1)
Assign(YL, 2)
Assign(XH, 3)
Assign(YH, 4)
Assign(DsDx, 5)
mfc2 XL, spriteXY[0]
mfc2 YL, spriteXY[8]
mfc2 XH, spriteXY2[0]
mfc2 YH, spriteXY2[8]
andi YL, YL, 0x0fff
sll XL, XL, 12
or XL, XL, YL
andi YH, YH, 0x0fff
sll XH, XH, 12
or XH, XH, YH
mfc2 DsDx, spriteSC[2]
EndAssign(YL, 2)
EndAssign(YH, 4)
EndAssign(spriteXY2, v2)
#---------------------------------------------------------------------
# Copy Mode に対する処理
#
# /* S scale を 4 倍にし, 終了座標を 1 Pixel 減らす */
# if ((saved_othermode_h & (3<<G_MDSFT_CYCLETYPE))
# == G_CYC_COPY){
# scaleX <<= 2;
# objXR -= 4;
# objYD -= 4;
# }
#---------------------------------------------------------------------
Assign(othermode, 2)
lbu othermode, RSP_STATEP_OTHER_H+1(zero)
andi othermode, othermode, 0x20
beq othermode, zero, SomeCycleMode
nop
sll DsDx, DsDx, 2
addi XH, XH, -0x4004
SomeCycleMode:
EndAssign(othermode, 2)
#---------------------------------------------------------------------
# Tile 記述子の設定
#---------------------------------------------------------------------
Assign(tile, 2)
lbu tile, RSP_STATEP_RENDERTILE(zero)
xori tile, tile, 0x02
sb tile, RSP_STATEP_RENDERTILE(zero)
#---------------------------------------------------------------------
# Tilesync コマンドの処理
# もし rdpstat = RDP_STAT_PRIMITIVE(tile) なら Tilesync
#---------------------------------------------------------------------
lb sys1, RSP_STATEP_RDP_STAT(zero) # 状態の取得
sbv _TILESYNC, 0(outp)
bne tile, sys1, NoNeedSync2 # 状態の比較
sb tile, RSP_STATEP_RDP_STAT(zero) # 状態の更新
addiu outp, outp, 8
NoNeedSync2:
#---------------------------------------------------------------------
# SetTile コマンドの作成
#---------------------------------------------------------------------
Assign(Dfmt, 4)
Assign(Dsiz, 6)
Assign(Dstr, 7)
Assign(Dadr, 8)
Assign(Dpal, 9)
Assign(Dlow, 10)
slv twindow[4], oRSPOBJ_VSCRATCH(vecptr)
lw Dlow, oRSPOBJ_VSCRATCH(vecptr)
lbu Dfmt, RSP_SPR_IMGFMT(sptr)
lbu Dsiz, RSP_SPR_IMGSIZ(sptr)
lhu Dstr, RSP_SPR_IMGSTR(sptr)
lhu Dadr, RSP_SPR_IMGADRS(sptr)
lbu Dpal, RSP_SPR_IMGPAL(sptr)
sll Dfmt, Dfmt, 21
sll Dsiz, Dsiz, 19
or Dfmt, Dfmt, Dsiz
sll Dstr, Dstr, 9
or Dfmt, Dfmt, Dstr
or Dfmt, Dfmt, Dadr
sw Dfmt, 0(outp) # 頭の 1byte は上書かれる
sbv _SETTILE, 0(outp)
sll Dpal, Dpal, 20
or Dpal, Dpal, Dlow
sw Dpal, 4(outp) # 頭の 1byte は上書かれる
sb tile, 4(outp)
EndAssign(twindow, v4)
EndAssign(Dfmt, 4)
EndAssign(Dsiz, 6)
EndAssign(Dstr, 7)
EndAssign(Dadr, 8)
EndAssign(Dpal, 9)
EndAssign(Dlow, 10)
#---------------------------------------------------------------------
# SetTileSize コマンドの作成
# gDPSetTileSize((*glistp)++,
# spriteRenderTile, 0, 0, sp->s.imageW/8-4, sp->s.imageH/8-4);
#---------------------------------------------------------------------
Assign(Dpc0, 4)
Assign(Dpc1, 6)
Assign(SH, 7)
Assign(TH, 8)
lhu SH, RSP_SPR_IMGW(sptr)
slv _SETTILESIZE, 8(outp)
lhu TH, RSP_SPR_IMGH(sptr)
andi SH, SH, 0x7ff8
sll SH, SH, 9
sra TH, TH, 3
or Dpc1, SH, TH
addi Dpc1, Dpc1, -0x4004
sw Dpc1, 12(outp)
sb tile, 12(outp)
EndAssign(sptr, 20)
EndAssign(Dpc0, 4)
EndAssign(Dpc1, 6)
EndAssign(SH, 7)
EndAssign(TH, 8)
#---------------------------------------------------------------------
# RDP コマンドの作成
#
# +-------------------------------------------------+
# |cmd:8| XH:12 | YH:12 | |tile:3| XL:12 | YL:12 |
# +-------------------------------------------------+
# | S:16 | T:16 | DsDx:16 | DtDy:16 |
# +-------------------------------------------------+
#
#---------------------------------------------------------------------
Assign(head, 4)
sw XH, 16(outp)
sbv _TXTRRECT, 16(outp)
sw XL, 20(outp)
sb tile, 20(outp)
ssv spriteST[0], 24(outp)
ssv spriteST[8], 26(outp)
sh DsDx, 28(outp)
ssv spriteSC[10], 30(outp)
#---------------------------------------------------------------------
# outp バッファへの送信
#---------------------------------------------------------------------
j OutputCloseGfxDone
addiu outp, outp, 32
EndAssign(head, 4)
EndAssign(tile, 2)
EndAssign(XL, 1)
EndAssign(XH, 3)
EndAssign(DsDx, 5)
EndAssign(spriteST, v7)
EndAssign(spriteSC, v13)
#----------------------------------------------------------------------------
# case_G_OBJ_RECTANGLE_R:
# 相対指定矩形 OBJECT のための座標変換
#----------------------------------------------------------------------------
.symbol case_G_OBJ_RECT_R, case_G_OBJ_RECT
FixedAssign(sprite, v2) # objX,sclX,imgS,imgW, objY,sclY,imgT,imgH
FixedAssign(rsmode, v3) # RenderMode AA/BLP パラメータ
FixedAssign(shrink, v4) # RenderMode Shrink パラメータ
FixedAssign(sptr, 20) # uObjSprite へのポインタを設定 = dmem_adrs
Assign(scale, v7)
Assign(baseXY, v8)
case_G_OBJ_RECT_R_Txtr:
lqv sprite[0], RSP_SPR_OBJX(sptr)
case_G_OBJ_RECT_R_Fix:
lsv scale[2], oRSPOBJ_BASE_SCALEX(vecptr)
lsv scale[10], oRSPOBJ_BASE_SCALEY(vecptr)
lsv baseXY[0], oRSPOBJ_MATRIX_X(vecptr)
lsv baseXY[8], oRSPOBJ_MATRIX_Y(vecptr)
#---------------------------------------------------------------------
# obj[XY] の小数点位置調整
# (s13.2)->(s18.13)
#---------------------------------------------------------------------
Assign(objXY, v9)
Assign(objXYf, v10)
vmudm objXY, sprite, _0x0800
vmadn objXYf, vconst, _0x0000
#---------------------------------------------------------------------
# scale[XY] 値の逆数を計算する
# 1/(s5.10) = (s10.21)
#---------------------------------------------------------------------
Assign(iscalei, v11)
Assign(iscalef, v12)
vrcp iscalef[0], scale[1]
vrcph iscalei[0], vtmp[0]
vrcp iscalef[4], scale[5]
vrcph iscalei[4], vtmp[0]
#-------------------------------------------------------------
# vrcp 命令では 1 の逆数が 1 にならないので値の補正をする
#
# 0x00010000 の逆数が 0x0001ffff となるので
# High 部分を Low に加算してやる
# 形としては 0x0001.0001 を乗ずることになる.
#
# 負の値対策のため, 以下の様にする
#
vmudn vtmp, vone, iscalei
vmadn iscalef, iscalef, _0x0001
vmadh iscalei, iscalei, _0x0001
#---------------------------------------------------------------------
# スケール値の掛け合わせ
# (s15.16)*(s5.10)=(ss20.26)=(s5.10)
#---------------------------------------------------------------------
Assign(scalef, v13)
vmudm scale, scale, _0x0040 # S * U
vmadn scalef, vconst, _0x0000
vmudn vtmp, scalef, sprite
vmadh scale, scale, sprite # [1|5]
EndAssign(scalef, v13)
#---------------------------------------------------------------------
# obj[XY] / scale[XY] を計算する
# (s18.13)*(s10.21) = (s29.34) = (s13.18)
#---------------------------------------------------------------------
vmudl vtmp, objXYf, iscalef[0h]
vmadm vtmp, objXY, iscalef[0h]
vmadn spriteXYf, objXYf, iscalei[0h]
vmadh spriteXY, objXY, iscalei[0h]
EndAssign(objXY, v9)
EndAssign(objXYf, v10)
EndAssign(iscalei, v11)
EndAssign(iscalef, v12)
#---------------------------------------------------------------------
# AA/Bilerp に伴う座標シフトの処理
# サブピクセル切捨ておよび座標値の加算
#---------------------------------------------------------------------
vadd baseXY, baseXY, shrink[iSHRINK_R_OBJXY] # [0|4]
vand baseXY, baseXY, rsmode[iCUT_SUBPIX] # [0|4]
vmadn spriteXY, spriteXY, _0x0001
#---------------------------------------------------------------------
# データのマージ
#---------------------------------------------------------------------
vmov sprite[1], scale[1]
j case_G_OBJ_RECT_R_Ret
vmov sprite[5], scale[5]
EndAssign(sptr, 20)
EndAssign(sprite, v2) # imageS,imageT,imageW,imageH
EndAssign(rsmode, v3)
EndAssign(shrink, v4)
EndAssign(spriteXY, v5)
EndAssign(scale, v7)
EndAssign(baseXY, v8)
EndAssign(spriteXYf, v6)
#
# gs2bg1cycL.s とサイズを合わせるためのダミーデータ
#
#ifndef UCODE_S2DEX2
nop # Dummy
nop # Dummy
#endif
case_G_OBJ_RECT_end:
#
# gs2bg1cyc で参照するアドレスの宣言
#
.symbol adrs_G_OBJ_RECT, case_G_OBJ_RECT
.symbol adrs_G_OBJ_RECT_Txtr, case_G_OBJ_RECT_Txtr
.symbol adrs_G_OBJ_RECT_Txtr_NEG, (case_G_OBJ_RECT_Txtr|0x8000)
.symbol adrs_G_OBJ_RECT_end, case_G_OBJ_RECT_end
/*======== End of gs2rect.s ========*/