ボタン入力とデバッグ

ボタン入力はアドレス0x4000130をu16単位で参照します。下位のビットから順番に、Aボタン、Bボタン、セレクトボタン、スタートボタン、十字キーの→、←、↑、↓、Rボタン、Lボタンとなっています。ビットが立っている時は押されていない状態、ビットが立っていない時は押されている状態です。どの程度の強さで押されているか、といった判定はできません。

ビット1514131211109876543210
ボタンLRSTSLBA

取得方法

キー入力を取得するにはメインループ中で毎回状態をチェックするか、割り込み機能を使って取得します。今回は簡単な前者の方法を使ってみましょう。以下のenumを用意します。

#define REG_KEYINPUT	*(vu16*)(REG_BASE + 0x130)  // Key Input

typedef enum KEYPAD_BITS {
	KEY_A		=	(1<<0),	/*!< keypad A button */
	KEY_B		=	(1<<1),	/*!< keypad B button */
	KEY_SELECT	=	(1<<2),	/*!< keypad SELECT button */
	KEY_START	=	(1<<3),	/*!< keypad START button */
	KEY_RIGHT	=	(1<<4),	/*!< dpad RIGHT */
	KEY_LEFT	=	(1<<5),	/*!< dpad LEFT */
	KEY_UP		=	(1<<6),	/*!< dpad UP */
	KEY_DOWN	=	(1<<7),	/*!< dpad DOWN */
	KEY_R		=	(1<<8),	/*!< Right shoulder button */
	KEY_L		=	(1<<9),	/*!< Left shoulder button */

	KEYIRQ_ENABLE	=	(1<<14),	/*!< Enable keypad interrupt */
	KEYIRQ_OR	=	(0<<15),	/*!< interrupt logical OR mode */
	KEYIRQ_AND	=	(1<<15),	/*!< interrupt logical AND mode */
	DPAD 		=	(KEY_UP | KEY_DOWN | KEY_LEFT | KEY_RIGHT) /*!< mask all dpad buttons */
} KEYPAD_BITS;

横道な話

ところで入力の説明が簡単すぎたので別の話をさせてもらいます。今まで何気なくビットマップモードから説明をしてきました。REG_DISPCNTなどのレジスタに設定したり、VRAMに色データを設定したり、そして今回のREG_KEYINPUTは値を読み取ってボタンの状態を確認しています。もう少し概念的にいうと、決められた設定データをアドレスに配置する、または決められたアドレスの値を調べる、という考え方に集約されます。設定を忘れたり、データを配置し忘れると当然うまくいきません。ここではプログラマーの意図した結果になっているのか?という確認方法をまとめてご紹介します。

Tools -> Memory viewer

エミュレータのMemory viewerです。Toolsからぶら下がっているものはすべて有用なので一度確認しておくことをおすすめします。

gritの出力結果

gritのオプションを間違うことはよくあることです。自分の意図したサイズかどうか、あと1、2バイト目のデータ構造ぐらいは確認した方がいいかもしれません。

printfデバッグ

私のサンプルコード限定ですけれど、使い方は以下のとおりです。

u32 x = 1234;

TRACE("%d %x\n", x, x);

出力結果はエミュレータのTools->Loggingで確認できます。この関数は自作したものなので標準ライブラリと関係ありません。標準的な機能は網羅されていないと思ってください。原理についてはDoc.10 エミュレータのデバッグコンソールに詳しく書かれています。ところで、そろそろ標準ライブラリは使えないのかという疑問も出てくると思います。

#include <stdio.h>

というように山括弧を使えば使用できますが、入出力関係の関数は全滅です。なぜならfopen、fgetcはファイルシステムがないので使えず、scanfはキーボード入力が物理的にないので使えず、printfはそもそも日本語フォントが内蔵されておらず、表示手段もないので使えず。。OSがないってなんて不便なんや、と文句いいたくなりますね。有用なのは数学関係の関数でしょうか。

#include <math.h>

ただ標準ライブラリは全部カードリッジ領域固定なのでスピードが出ません。あとROMのサイズも増大するのであまりおすすめしません。

ボタン入力

ボタン入力のサンプルコードです。

#include "lib/gba.h"

//---------------------------------------------------------------------------
void WaitForVsync(void)
{
	while(*(vu16*)0x4000006 >= 160) {};
	while(*(vu16*)0x4000006 <  160) {};
}
//---------------------------------------------------------------------------
int main(void)
{
	SetMode(MODE_3 | BG2_ENABLE);

	u32 x = 0;

	for(;;)
	{
		WaitForVsync();

		if( !(REG_KEYINPUT & KEY_UP)   ) TRACE("上 ボタン\n");
		if( !(REG_KEYINPUT & KEY_DOWN) ) TRACE("下 ボタン\n");
		if( !(REG_KEYINPUT & KEY_RIGHT)) TRACE("右 ボタン\n");
		if( !(REG_KEYINPUT & KEY_LEFT) ) TRACE("左 ボタン\n");

		if( !(REG_KEYINPUT & KEY_A)    ) TRACE("10進=%d 16進=0x%x 16進4桁=0x%04x \n", x, x, x);
		if( !(REG_KEYINPUT & KEY_B)    ) TRACE("変数x++ \n", x++);
	}
}

ちなみにボタン入力はパソコンの物理キーボードの性能に依存しています。たとえば上下右左の4つのボタンを同時にした結果、正しいデバック表示になるかというとかなり怪しいです。個人的には安いキーボードほど同時ボタン処理が適当なイメージを持っています。実機の場合とでは動作が違うということを覚えておいてください。

デバッグ画面

1.png

履歴


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