index
テキスト表示

ascii.c ASCII文字をタイル表示するプログラム例です。タイルに文字フォントを画像として格納して利用します。GBAの開発環境には文字フォントは含まれていませんので、自分で用意する必要があります。8x8 ドットのフォントがあれば、タイルに割り当てることができます。
ascii.c
/****************************************/
/*		ASCII Characters	*/
/****************************************/

#include "gba.h"
#include "font8.c"		// Font data
void init_screen(void);

hword* bcolor = (hword*) BG_PALETTE;	// 0x05000000
hword* tile   = (hword*) VRAM_TILE(0);	// 0x06000000
hword* map    = (hword*) VRAM_MAP(16);	// 0x06008000

font8.c にフォントデータが入っています。フォントデータの内容は、このページの下のほうで解説しています。VRAM および背景パレットの使用領域を配列に割り当てます。gba.h に定義されたマクロにより VRAM_MAP(16) = 0x0600 8000, VRAM_TILE(0) = 0x0600 0000, BG_PALETTE = 0x0500 0000 の数値を、ポインタとして設定しています。
Fig.2-1
int main() {
  int i, j;

  // Initialize text screen
  init_screen();
パレットとタイルを設定する関数です。ページの下のほうの説明を見てください。
  // Display 256 characters

  for (i = 0; i < 16; i++) {
    for (j = 0; j < 16; j++) {
      map[ (i + 2) * 32 + (j + 7) ] = i * 16 + j;
     }
   }
マップ領域の配列 map[] にマップデータを書き込みます。8x8pixのフォントでは、1タイル1文字が割り当てられますので、1 Byte のアスキーコードは、16 x 16 タイルの領域で全文字が表示できます。仮想スクリーンサイズは、32 x 32 タイルを使用しています。
Fig.2-2

  // Loop
  while (1);
 }
電源を切るまで画面表示するための無限ループです。
void init_screen(void) {

  int i, row, col, bit, val;

  // Initialize palette

  bcolor[ 1 ] = RGB( 0,  0,  0);	// Black
  bcolor[ 2 ] = RGB(31, 31, 31);	// White

パレット領域の配列 bcolor[] に白黒文字の色データを書き込みます。
// Initialize tiles with ASCII bitmap data (8x8 Font)

  for (i = 0; i < 96; i++) {			// Max ASCII code number
    for (row = 0; row < 8; row++) {		// Row number of font bitmap
      for (col = 7; col >= 0; col--) {		// Column number of font bitmap
        bit = (Font[i][row] & (1 << col)) ? 2 : 1;
        if (col % 2)
          val = bit;
        else
          tile[ ((i + 32) * 32) + (row * 4) + ((7 - col) / 2)] = val + (bit << 8);
       }
     }
   }

フォントデータを、タイル領域の配列 tile[] に書き込みます。実は、このフォントデータは、少し手抜きで 0 - 95 までの文字しかありませんので、一番外側のループは、そのようになっています。変数 bit の計算では、各行のビットマップが 0 か 1 かを判定して、0なら白(パレットの色番号2)1なら黒(パレットの色番号1)を変数 bit に代入しています。(1 << col) は、各行 8 ビットの各桁の値を調べるためのマスクです。次に、col が奇数なら、変数 bit は、そのまま 変数 val に代入され、col が偶数なら、変数 bit は、8 ビット左シフトされ、val に加算されます。これは、tile を 16 bit 整数として宣言したので、16 bit 1組で書き込むための工夫です。従って、col が偶数のとき、タイル領域の配列 tile[] にパレット番号が書き込まれます。タイルのアドレス計算は少し複雑なのですが、下の図を見て考えてください。(注)tile[ ((i+32)*32 +...] の部分で、(i +32) * 32 はおかしいと気付いた人がいるかもしれません。このフォントは、手抜きした分、ASCIIコードと文字の順番がずれてしまっているので、32文字分タイルの格納場所をシフトして、ASCII コードとタイルのポインタが一致するようにしました。
Fig.2-3
  // Start LCD display (MODE 0)
load_ioreg(BG0_CTL) = LCD_SIZE00 | LCD_COLOR256 | LCD_BGTILE(0) | LCD_BGMAP(16);
load_ioreg(LCD_CTL) = LCD_MODE0 | LCD_BG0;          

}
BG0_CTL = 0x0400 0008 の BG0用背景コントロールレジスタに下記の背景設定を書き込んでいます。gba.h の中身を確認してください。
LCD_SIZE000x00000000000000000000
LCD_COLOR2560x00800000000010000000
LCD_BGTITLE(0)0 << 20000000000000000
LCD_BGMAP(16)10000 << 80001000000000000
OR0001000010000000
この結果、仮想スクリーンサイズは00番(32 x 32 タイル)、VRAMマップブロック開始アドレス16 (= 0x0600 8000)、カラーモード256色、VRAMタイルブロック開始アドレス0 (= 0x0600 0000)となります。詳しくは、ハードウエアの概要のページで確認しよう。次に、LCDコントロールレジスタに、モード0を指定し、背景BG0をONにしています。

font8.c
const unsigned char Font[][8] =  {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},
{0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x00,},
{0x6C,0x6C,0x48,0x00,0x00,0x00,0x00,0x00,},
{0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00,},
  :
  :
};
フォントデータファイル font8.c の内容。他のフォントが欲しい場合は、ネットを探してみよう。面倒でなければお絵かきツールでタイルを作るという手もある。

フォントデータは、8 x 8 のビットマップ256枚を、Font[ASCII code][Row number]の配列に格納します。従って、1行8bit x 8行 = 8Byte で1文字となっています。


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

(c) Kanazawa Univ., 2004