Doc.11 英数字の表示方法(ビットマップモード) †GBAにはフォントを表示してくれる機能がないので自前に用意しなくてはいけません。 以下に紹介したフォントはライセンスがかなり緩いものです。 フォントの形式はbdfを使おう †bdf形式はフォントを構成しているドットの集まりを記述したものです。 ここでは漢字12x10ドットフォントのk6x10.bdfを例に見ていきたいと思います。
注意してほしい部分はBITMAP〜ENDCHARの間です。 00100000 00100000 00100000 00100000 00100000 00100000 00000000 01100000 01100000 00000000 2進数に変換してみたのが上記です。
このbdfファイルは、160文字入っていることになっています。 bdfからbmp(ビットマップ)へ †bdfの内容はどのように文字が並んでいたり、字体がさっぱりわからないと思います。 bdf2bmp.exe -s 0 -c 160 k6x10.bdf k6x10.bmp
![]() 最初の字体は「 」(空白スペース)、次に「!」(ビックリマーク)、「”」(ダブルクォーテーション)。 0x20 (空白スペース) 0x21 ! 0x22 " 0x23 # 0x24 $ 0x25 % (以下略・・・) 1文字6x10ドット、160文字あるので画像全体の大きさは960x10ドットとなります。 gritを使ってmode3の画像に変換 †さて、k6x10.bmpをgrit(GBA用画像変換ツール)を使ってmode4用に変換をします。
仮に2文字目の「!」(ビックリマーク)をGBA上に表示したい場合、位置は次の計算でもとめられます。 1行目の位置 = 2文字目(何文字目かという情報) * 6ドット(1文字分の横のサイズ) 2行目以降の位置も、先の計算式を少し拡張して使います。 2行目以降の位置 = 2文字目(何文字目かという情報) * 6ドット(1文字分の横のサイズ) + (コピーしたい行 * 960ドット(画像ファイル全体の横のサイズ)) ビットマップモードでフォントの表示例 †今回の例では、トップダウンで見ていった方がわかりやすいのでmain関数から説明します。 int main(void) { SetMode(MODE_3 | BG2_ENABLE); ST_FONT f; f.pDat = (u8*) &k6x10Bitmap; // データのポインタ f.imgCx = 960; // データの横サイズ f.cx = 6; // 1文字の横サイズ f.cy = 10; // 1文字の縦サイズ Mode3DrawFontChr(&f, 0, 0, '!', RGB5(31,31,31)); Mode3DrawFontStr(&f, 16, 16, "ABCDEF #$%&", RGB5(31,31,31)); Mode3DrawFontStr(&f, 16, 32, "123456 +-*/", RGB5(31,31, 0)); for(;;) { WaitForVsync(); } } この中で出てくるST_FONT構造体は、フォントを表示するために必要なパラメータを設定します。 typedef struct { u8* pDat; u16 imgCx; u16 cx; u16 cy; } ST_FONT; Mode3DrawFontChrは先ほど説明した内容をコードに落としたものです。 void Mode3DrawFontChr(ST_FONT* p, s32 sx, s32 sy, u16 chr, u16 col) { // 書き込む起点位置を求めます u16* pScreen = (u16*)VRAM + (sy * 240) + sx; // 書き込むフォントデータの位置を求めます u8* pDat = p->pDat + (chr - 0x20) * p->cx; s32 x, y; for(y=0; y<p->cy; y++) { for(x=0; x<p->cx; x++) { if(pDat[y*p->imgCx + x] == 0x00) { continue; } pScreen[y*240 + x] = col; } } } 最後にMode3DrawFontStr関数ですが、 void Mode3DrawFontStr(ST_FONT* p, s32 sx, s32 sy, char* str, u16 col) { u16 chr; s32 i=0, x=0, y=0; for(;;) { chr = str[i++]; if(chr == '\0') { return; } // 改行処理 if(sx + x >= 240) { x = 0; y += p->cy; if(sy + y + p->cy >= 160) { return; } } Mode3DrawFontChr(p, sx + x, sy + y, chr, col); x += p->cx; } } 動作画面 †![]() 履歴 †
|