拡大縮小1

拡大縮小はBGやスプライトに対して行える機能です。ハードウェア的制約があるので注意してください。表のように一部のBGのみとなっています。

タイルモードモード1のBG2、モード2のBG2,BG3
ビットマップモードBG2のみ
スプライト128個(すべて)

REG_BGxPA、REG_BGxPB、REG_BGxPC、REG_BGxPD、REG_BGxX、REG_BGxY

I/OレジスタはBG2用とBG3用に分かれています。それぞれは拡大縮小パラメータ4つ(PA,PB,PC,PD)と、始点位置を決めるxX、xYで構成されています。

#define REG_BG2PA	*((vu16 *)(REG_BASE + 0x20))
#define REG_BG2PB	*((vu16 *)(REG_BASE + 0x22))
#define REG_BG2PC	*((vu16 *)(REG_BASE + 0x24))
#define REG_BG2PD	*((vu16 *)(REG_BASE + 0x26))
#define REG_BG2X	*((vu32 *)(REG_BASE + 0x28))
#define REG_BG2Y	*((vu32 *)(REG_BASE + 0x2c))

#define REG_BG3PA	*((vu16 *)(REG_BASE + 0x30))
#define REG_BG3PB	*((vu16 *)(REG_BASE + 0x32))
#define REG_BG3PC	*((vu16 *)(REG_BASE + 0x34))
#define REG_BG3PD	*((vu16 *)(REG_BASE + 0x36))
#define REG_BG3X	*((vu32 *)(REG_BASE + 0x38))
#define REG_BG3Y	*((vu32 *)(REG_BASE + 0x3c))

拡大縮小パラメータは4つの数値を組み合わせることで、さまざまな効果を出すことができます。今回は拡大縮小のための最小限の解説を行います。このパラメータの基本(元と同じ画像を表示)は、PAから順番に256,0,0,256です。拡大・縮小表示したい場合は、縦の変化率がPAとPB、横の変化率がPCとPD、に一定の値をかけます。かける値は倍率の逆数になります。つまり2倍にして表示したい場合は2で割ればいいことになって、逆に1/2に表示したい場合は2をかけます。

倍率PA~PD
200%128, 0, 0, 128
100%256, 0, 0, 256
50%512, 0, 0, 512

BGの拡大縮小表示

#include "lib/gba.h"
#include "irq.arm.h"
#include "key.h"
#include "font.h"

//---------------------------------------------------------------------------
void ScaleBG2(u32 xsc, u32 ysc)
{
	REG_BG2PA = Div(256 * 100, xsc);
	REG_BG2PB = 0;
	REG_BG2PC = 0;
	REG_BG2PD = Div(256 * 100, ysc);
}
//---------------------------------------------------------------------------
int main(void)
{
	REG_WSCNT = 0x4317;

	IrqInit();
	KeyInit();
	FontInit();

	SetMode(MODE_3 | BG2_ENABLE);

	s32 x = 150;
	s32 y = 150;
	u16 cnt;

	REG_DMA3SAD = (u32)&imageBitmap;
	REG_DMA3DAD = (u32)VRAM;
	REG_DMA3CNT = (u32)(240*160) | (DMA_SRC_INC | DMA_DST_INC | DMA16 | DMA_ENABLE);

	for(;;)
	{
		VBlankIntrWait();

		FontDrawPrintf(16, 16, RGB5(31,31,31), "[%3d][%3d]", x, y);

		ScaleBG2(x, y);

		KeyExec();
		cnt = KeyGetCnt();

		if(cnt & KEY_UP   ) y--;
		if(cnt & KEY_DOWN ) y++;
		if(cnt & KEY_LEFT ) x--;
		if(cnt & KEY_RIGHT) x++;

		if(x <   1) x =   1;
		if(x > 200) x = 200;
		if(y <   1) y =   1;
		if(y > 200) y = 200;
	}
}

動作画面

履歴


トップ   一覧 検索 最終更新   ヘルプ   最終更新のRSS