英語では、Scale and Rotation
なので略して scalerot
と呼ばれることも多いです。また数学的にはアフィン変換とも呼ばれます。
伸縮回転とビットマップモードでは、BGスクロールレジスタとして、(テキストモードの)BGnOFS
の代わりにこちらが使用されます。
BGスクロールレジスタに入っている値は、伸縮回転とビットマップモードでは無視されます。
0x0400_0028/0x0400_002c - BG2X/BG2Y - BG2 X/YオフセットX(0-27bit) (W)
0x0400_0038/0x0400_003c - BG3X/BG3Y - BG3 X/YオフセットX(0-27bit) (W)
Bit Expl.
0-7 小数部分 (8 bits)
8-26 整数部分 (19 bits)
27 符号 (1 bit)
28-31 不使用
例えば、0x12を設定したい時は、分数部分は0x00、整数部分は0x12にしたいのでレジスタには 0x12 << 8
を格納することになります。
符号付きの32bit値を上記のレジスタに書き込むことができますが、このとき最上位bitは無視され、値は28bitに切り捨てられます。
上記の基準点(BGnX/Y
)は、VBlankの間に自動的に内部レジスタにコピーされ、最初の走査線の原点を指定します。内部レジスタは、各スキャンラインの後にdmxとdmy(PBとPD)によってインクリメントされます。
VBlank期間外にBGnX/Y
を変更すると即座に内部レジスタにコピーされます。
BGnX/BGnY
は、格納した値がそのまま画面上のBGのオフセットになるのでなく、後述の伸縮回転パラメータに影響されます。
BGが1/10に縮小される場合は、BGnX/BGnY
にセットした値の1/10だけ画面上で移動することになります。
また、BGが回転している場合は、回転したあとのBGの上下左右を基準に画像が移動します。
BGnX/BGnY
に格納する値の計算式は以下のようになります。
bgx = x1 - α*cos(θ-β)*hzoom
bgy = y1 - α*(-sin(θ-β))*vzoom
変数 | 内容 |
---|---|
bgx, bgy | BGオフセットレジスタ |
x1, y1 | BG面での回転の中心座標(x1,y1) |
hzoom, vzoom | 横・縦の拡大率 |
θ | 回転の角度 |
α | (0,0)から(x1,y1)までの長さ α = sqrt(x1*x1 + y1*y1) |
β | (0,0)から(x1,y1)までの角度 β = atan2(y1,x1) |
0x0400_0020 - BG2PA - BG2伸縮回転パラメータA (W)
0x0400_0022 - BG2PB - BG2伸縮回転パラメータB (W)
0x0400_0024 - BG2PC - BG2伸縮回転パラメータC (W)
0x0400_0026 - BG2PD - BG2伸縮回転パラメータD (W)
0x0400_0030 - BG3PA - BG3伸縮回転パラメータA (W)
0x0400_0032 - BG3PB - BG3伸縮回転パラメータB (W)
0x0400_0034 - BG3PC - BG3伸縮回転パラメータC (W)
0x0400_0036 - BG3PD - BG3伸縮回転パラメータD (W)
bit | 15 | 14-8 | 7-0 | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
内容 | 符号 | 整数部分 (7 bits) | 分数部分 (8 bits) |
伸縮回転パラメータの4つの数値(PA,PB,PC,PD)を組み合わせることで、伸縮や回転などさまざまな効果を出すことができます。
GBAでのアフィン変換は以下の行列を座標に対してかけることで行われます。
[PA, PB] [cos(θ)/Sx, -sin(θ)/Sx]
[PC, PD] = [sin(θ)/Sy, cos(θ)/Sy]
θ
: 回転角度Sx, Sy
: 拡大倍率
拡大倍率が逆数をとることに注意してください。
画像を2倍の大きさに拡大する場合は、
[1/2 * 256, 0]
[0, 1/2 * 256]
画像をX方向に2倍、Y方向にはそのままの大きさにする場合は、
[1/2 * 256, 0]
[0, 1 * 256]
画像を60度回転させる場合は、
[cos(π/3), -sin(π/3)]
[sin(π/3), cos(π/3)]
↓
[0.9921875 * 256, -0.8660254 * 256]
[0.8660254 * 256, 0.9921875 * 256]
となります。
画像をX方向に2倍、Y方向にはそのままの大きさにして、60度回転させるのを同時にやりたい場合には
[1/2, 0] [0.9921875, -0.8660254] [256, 0]
[0, 1] * [0.8660254, 0.9921875] * [0, 256]
↓
[1/2 * 0.9921875 * 256, 1/2 * (-0.8660254) * 256]
[ 0.8660254 * 256, 0.9921875 * 256]
↓
[127, 110.8512]
[221.7025, 254]
となります。
変換の結果、画像がBGの外にはみ出てしまう場合の挙動はBGモードによってことなります。
BGモードが1,2のときは、BG2CNT,BG3CNTのbit13で、無視するかwrap(1周)するか指定することができます。
BGモードが3,4,5のときははみでた部分は無視されます。