ビットマップモードの文字表示2

前回に続き、今度は日本語表示をしていきます。ただ漢字の個数が不明でどれぐらいのデータ量が増加するか検討もつきません。そこでプログラマー的視点に立って、ある程度の概算を出してみます。1ドット1バイト、1文字16x16ドットの場合16 * 16 = 256バイトです。文字数を大雑把に6000字とすると、6000 * 256 = 1,536,000バイト = 1.5MBという予想になります。本職のプログラマーが見たら卒倒しそうな数字ですが、せめて1ドット1ビット単位にしたらどうかと言ってきそうです。ここでは無視します。(ぉ

日本語を表示しよう

16進数の数字と文字を対応した表(テーブル)には代表的なものとしてSJIS、EUC、UTF-8などがあります。ここではSJISのみ扱います。たとえば表示したい文字列をSJISで表示してみると、以下のようになります。

猫 - 0x944c
ま - 0x82dc
ん - 0x82f1
ま - 0x82dc
1.png

1文字2バイト表現となっていて、つまり「Mode3DrawSJISStr(0, 0, "猫まんま")」っぽい関数を作り内部で文字コードと文字データを突き合せれば完成するわけです。前のサンプルコードと同じ・・・と行きたいところですが、そうは問屋が下ろしません。SJISコード表をよーくみると微妙な空白地帯が存在しており、空白文字が大量にあるということはそのままデータ量に跳ね返ってきます。ではどうするかというと、空白部分を除去したフォントシートと呼ばれるテキストを用意して、フォントデータのインデックスを求めます。

u8* pDat = pフォントデータ;
s32 i;

for(i=0; i<フォントシート内の文字数; i++)
{
	if(フォントシート[i] == 表示したい文字)
	{
		pDat += i * 横のドット分;
		break;
	}
}

// 描画処理

本職のプログラマーな方がみたら卒倒しそうなループ処理ですね。(爆

Mode3で日本語表示

今回もmain関数から見てみましょう。

int main(void)
{
	SetMode(MODE_3 | BG2_ENABLE);

	ST_FONT f;

	f.pDat   = (u8*)&mplus_j10rBitmap;
	f.imgCx  = 69630 + 2;		// +2は、gritのサイズ調整分
	f.cx     = 10;
	f.cy     = 11;

	f.pSheet = (u16*)&mplus_jfnt_txt;
	f.cnt    = 6963;

	Mode3DrawSJISStr(&f, 0, 0, "猫まんま", RGB5(31,31,31));

	(中略)

	for(;;)
	{
	    WaitForVsync();
	}
}

サンプルでは10x11ドットのmplusフォントを使用しました。6963文字入っています。

void Mode3DrawSJISStr(ST_FONT* p, s32 sx, s32 sy, char* str, u16 col)
{
	u16 chr;
	s32 i=0, x=0, y=0;

	for(;;)
	{
		chr = str[i] | (str[i+1] << 8);
		i += 2;

		if(chr == '\0')
		{
			return;
		}

		// 改行処理
		if(sx + x >= 240)
		{
			x  = 0;
			y += p->cy;

			if(sy + y + p->cy >= 160)
			{
				return;
			}
		}

		Mode3DrawSJISChr(p, sx + x, sy + y, chr, col);
		x += p->cx;
	}
}

2バイト文字を扱うため、chr変数に2バイト入れるようにしています。

void Mode3DrawSJISChr(ST_FONT* p, s32 sx, s32 sy, u16 chr, u16 col)
{
	u8* pDat = p->pDat;
	s32 i;

	for(i=0; i<p->cnt; i++)
	{
		if(chr == p->pSheet[i])
		{
			pDat += i * p->cx;
			break;
		}
	}

	u16* pScreen = (u16*)VRAM + (sy * 240) + sx;
	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;
		}
	}
}

フォントシートのインデックスを求めるだけで前回のコードとそれほど変わりありません。なお、main関数の「猫まんま」はソースコードのテキスト保存形式に依存しています。EUCで保存していたら表示されないので注意してください。

動作画面

2.png

履歴


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