index
仮想画面とスクロール

virtu.c 仮想画面は、最大 64x64 タイルまで使用可能です。さらに、仮想画面の端に来たときにマップを切り替えることにより、広大なマップを使用することが出来ます。このプログラム例では、カーソルキーにより、32x32 タイルの仮想画面上をスクロールする例を示します。また、マップの作成方法についても説明します。
virtu.c
/****************************************************************/
/*			Virtual Screen				*/
/****************************************************************/


#include "gba.h"
#include "back.h"
#include "back.c"
void init_screen(void);
void wait(int);
back.h は、背景画像のマップデータです。back.c は、背景画像のタイルデータとパレットデータです。これらの作り方は、ページの最後のほうに記載してあります。
hword* bcolor = (hword*) BG_PALETTE;

// Screen definition
screen plane[ 1 ] = {
	{ (hword*) VRAM_MAP(16), (hword*) VRAM_TILE(0), 0, 0 }	// Page 0
};
背景パレットの先頭アドレス 0x05000000は、2 Byte 配列 bcolor にポインタとして設定されています。screen は、gba.h の中で、定義された構造体(マップデータ、タイルデータ、x座標、y座標)です。この構造体は、複数画面制御を簡単に行うために定義されたものですが、この例では、背景画像1枚しか使用しませんので、配列要素は1個だけになっています。スカラーとして定義することもできます。
int main() {
	int key, xoff = 0, yoff = 0; // Key status, x-offset, y-offset
キー入力状態を代入する変数 key, 仮想画面上のLCD画面の左上座標(オフセット)を記憶するための変数、(xoff, yoff) を宣言します。
	// Initialize screen
	init_screen();
init_screen() は、背景の設定を行います。ページの後ろのほうを参照。
	// Key scan loop
	while (1) {
		key = gba_reg(KEY_STA);
		if ((key & KEY_ALL) == KEY_ALL)
			continue;
		key = key ^ KEY_ALL;
キーステータスレジスタから、key 変数にキー入力状態を取得し、key & KEY_ALL(全キー入力ビットマスク) により、キー入力を確認。キー入力が無ければ、ループ先頭に戻り、キー入力があれば、KEY_ALL との EXOR によりビット反転を行う。詳しくは、キー入力と複数画面合成のページを参照。
		if (key & KEY_UP) {
			if (yoff == 0)
				continue;
			yoff--;
			gba_reg(BG0_VOFFSET) = yoff;
		}
		else if (key & KEY_DOWN) {
			if (yoff == (256 - (20 * 8)))
				continue;
			yoff++;
			gba_reg(BG0_VOFFSET) = yoff;
		}
		else if (key & KEY_RIGHT) {
			if (xoff == (256 - (30 * 8)))
				continue;
			xoff++;
			gba_reg(BG0_HOFFSET) = xoff;
		}
		else if (key & KEY_LEFT) {
			if (xoff == 0)
				continue;
			xoff--;
			gba_reg(BG0_HOFFSET) = xoff;
		}
4方向各々のカーソルキーのビットマスク KEY_UP, KEY_DOWN, KEY_RIGHT, KEY_LEFT により、どの方向のキーが押されているか判定し、それに応じて、(xoff, yoff) をインクリメントまたはデクリメントする。但し、LCDが仮想画面の端に来ている場合に、さらにLCD座標を変更すると仮想画面からはみ出てしまうので、LCD表示領域が、仮想画面の端に来ていないか調べて、端まで来ていたら、ループ先頭に戻っています。仮想画面の大きさは、32x32タイル(背景コントロールレジスタポインタLCD_SIZE00で指定)に相当します。タイルは、8x8 pix なので、仮想画面サイズは、256x256 pix となります。LCD のサイズは、 30x20 タイルです。上のLCD表示領域の判定条件を、よく確認してください。また、仮想画面からはみ出すとどうなるか試してみてください。オフセットは、pix 単位で指定できますので、スムーズなスクロールが可能です。
		wait(80);
	};
}
スクロール速度調節用の、時間調整用ループ。
void init_screen(void) {

	int i;

	// Initialize palette
	for (i = 0; i < 256; i++)
		bcolor[ i ] = back_pal[ i ];

	// Setup tiles for background
	for (i = 0; i < 8 * 2 * 32; i++)
		plane[ 0 ].tile[ i ] = back_data[ 2 * i ] + (back_data[ 2 * i + 1] << 8);

	// Setup the map for background
	for (i = 0; i < 32 * 32; i++)
		plane[ 0 ].map[ i ] = back[ i ];
背景用パレット、タイルデータ、マップデータを、screen 構造体を用いて、パレットおよびVRAMに書き込んでいる。
	// Start LCD display
	gba_reg(BG0_CTL)  =	LCD_SIZE00  |
				LCD_COLOR256 |
				LCD_BGTILE(0) |
				LCD_BGMAP(16);
	gba_reg(LCD_CTL) =	LCD_BG0 |
				LCD_MODE0;
}
背景コントロールレジスタに、サイズ32x32タイル、パレット色数256色、タイル領域0番、マップ領域16番を設定。背景は、BG0番を使用。背景データの使用メモリアドレスマップは、自分で確認してみてください。
void wait(int time) {

	int i, j;

	for (i = 0; i < time; i++)
		for (j = 0; j < time; j++) ;
}
スクロール速度調節用の、時間調整用ループ。

back.c
const unsigned char back_data[8*2*64] = {
0x15,0x33,0x13,0x36,0x36,0x36,0x47,0x36,
0x15,0x36,0x33,0x36,0x36,0x2C,0x33,0x36,
 :
 :
};

const unsigned short back_pal[256] = {
0x0000,0x0842,0x1084,0x18C6,0x18C6,0x294A,0x318C,0x318C,
0x39CE,0x4631,0x4E73,0x4E73,0x56B5,0x5EF7,0x6739,0x6739,
 :
 :
};
全面を一枚の画像をタイルに分割して背景にする方法を、キー入力と複数画面合成のページで説明しました。この場合には、マップは、bmp2rgb2 が自動的に作成したものをそのまま使用しました。ゲームでは、少数のタイルを組み合わせて、所謂、ダンジョンマップを作成することがよくあります。まず、下のようなタイルパターンを用意します。GBAのタイルの単位は、8x8pixですので、8の倍数の長さのタイルパターンが必要です。この例では、16x16pixのものを4種類用意しました。これらのタイルパターンをフォトレタッチやお絵かきツールで結合します。縦長でも横長でもOKです。色は256色にして、Windows BMP 形式で保存します。これを、bmp2rgbで、GBAのRGB形式に変換します。*.c ファイルに、パレット、タイル、マップのデータが保存されていますが、パレットとタイルデータのみ使用します。このツールの出力するタイルデータは、8 bit 単位の配列になっているので、16 bit 幅のVRAMに読み込むときには、注意が必要です。
Tile data

back.h
const unsigned short back[] = {

6,7,6,7,6,6,6,6,
6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,
6,6,6,6,6,6,6,6,
 :
 :
};
マップは、自力でこつこつ作成してもよいのですが、やはり画面をみながらでないと、かっこいいマップはできません。ここでは、WideMapEditorというツールを使用しました。上で作成した、タイルパターンの Windows BMP 画像を読み込み、マウスでクリックしていくと、マップ画像が出来上がっていきます。8x8 タイルや 16x16 タイル単位でも操作することが出来て大変便利なツールです。完成したら、GBA用ファイルを出力します。*.h を上書きするか聞いてきますが、上書きでOKです。


お問い合わせはこちらまで: kitagawa@is.t.kanazawa-u.ac.jp

(c) Kanazawa Univ., 2004