2009年09月10日


広告


NP2 for PSPのキー入力あたりを解析する

NP2でキー入力処理を行っているのは、
「NP2 for PSPのmain()関数を解析する」で解説したメインループの、最初に呼び出されるtaskmng_rol()という関数です。
この中で、
・左トリガーで出るメニュー
・右トリガーで出るソフトキーボード
・マウスモードやキーモードでのパッド、ボタンの操作
を行っている。

PSPのデジタル、アナログパッド、ボタンが押されたかどうかは以下の様にして判断している。

SceCtrlData psppad;
sceCtrlReadBufferPositive(&psppad, 1);

SceCtrlData構造体はPSPSDKのpsp/sdk/include/pspctrl.hで以下の様に定義されている。

typedef struct SceCtrlData {
/** The current read frame. */
unsigned int TimeStamp;
/** Bit mask containing zero or more of ::PspCtrlButtons. */
unsigned int Buttons;
/** Analogue stick, X axis. */
unsigned char Lx;
/** Analogue stick, Y axis. */
unsigned char Ly;
/** Reserved. */
unsigned char Rsrv[6];
} SceCtrlData;

アナログパッドに関してはLx, Lyで移動量が、デジタルパッドを含むボタンに関しては、Buttonsに以下の様に定義されているので、各ビットを見れば、どれが押されたかが分かる。

enum PspCtrlButtons
{
/** Select button. */
PSP_CTRL_SELECT = 0x000001,
/** Start button. */
PSP_CTRL_START = 0x000008,
/** Up D-Pad button. */
PSP_CTRL_UP = 0x000010,
/** Right D-Pad button. */
PSP_CTRL_RIGHT = 0x000020,
/** Down D-Pad button. */
PSP_CTRL_DOWN = 0x000040,
/** Left D-Pad button. */
PSP_CTRL_LEFT = 0x000080,
/** Left trigger. */
PSP_CTRL_LTRIGGER = 0x000100,
/** Right trigger. */
PSP_CTRL_RTRIGGER = 0x000200,
/** Triangle button. */
PSP_CTRL_TRIANGLE = 0x001000,
/** Circle button. */
PSP_CTRL_CIRCLE = 0x002000,
/** Cross button. */
PSP_CTRL_CROSS = 0x004000,
/** Square button. */
PSP_CTRL_SQUARE = 0x008000,
/** Home button. In user mode this bit is set if the exit dialog is visi
ble. */
PSP_CTRL_HOME = 0x010000,
/** Hold button. */
PSP_CTRL_HOLD = 0x020000,
/** Music Note button. */
PSP_CTRL_NOTE = 0x800000,
/** Screen button. */
PSP_CTRL_SCREEN = 0x400000,
/** Volume up button. */
PSP_CTRL_VOLUP = 0x100000,
/** Volume down button. */
PSP_CTRL_VOLDOWN = 0x200000,
/** Wlan switch up. */
PSP_CTRL_WLAN_UP = 0x040000,
/** Remote hold position. */
PSP_CTRL_REMOTE = 0x080000,
/** Disc present. */
PSP_CTRL_DISC = 0x1000000,
/** Memory stick present. */
PSP_CTRL_MS = 0x2000000,
};

NP2 for PSPのtaskmng_rol()では、前回のパッド情報をbutton_downというstaticなローカル変数に保存している。そして以下の様に単純に押された、という情報だけでなく、「今回初めて押された」などの情報を得ている。

// 前回と変化のあったbitを立てる
button_changing = psppad.Buttons ^ button_down;
// 今回初めて押された = 前回と変化がある & 今ボタンが押されている
beingdown = button_changing & psppad.Buttons;
// 今回初めてはなされた = 前回と変化がある & 前回押されていた
beingup = button_changing & button_down;
// 変化のあったbitを反転させる
button_down ^= button_changing;

実際にボタンが押されてPC-98コアにキーコードを送っているのはmouse_98key_mode()。ここに送信するキーコードがあるので、ここを細工すればボタンを押したときのキーが変更できる。後は設定ファイルの構文解析とGUIによる設定の選択を作ればキーコンフィグのできあがり。
まぁ、なんとかなりそうですね。




タグ:PSP NP2 for PSP
posted by ひっそりぃ at 2009/09/10 16:39 | Comment(3) | TrackBack(0) | NP2 for PSP | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
こんにちは。

sceCtrlReadBufferPositiveは、連続で読みに行くと、2回目以降が非常に遅くなります。
sceCtrlPeekBufferPositiveだと、この問題は無い様です。

NP2のもっさりぃには、あまり効果はないかも知れませんが、参考まで。
Posted by at 2009年09月27日 22:25
情報ありがとうございます。

ちょっとググって見たら以下がみつかりました。
ttp://forums.qj.net/zx-81s-homebrew-releases/146232-development-question.html

Peekだとpollingして即読み、Readだとvsyncの1/60秒同期のタイミングで読む。
処理が軽いループでpeekを使うとpollingとキー処理で重くなったり、plugin等の別スレッドに処理が回らなくなる。
別の場所でvblank待ちをしているなら、peekの方が処理が早いし、vblank待ちのところで別のスレッドに処理をまわせる。

という感じでしょうか。

NP2では画面の書き換え時(表と裏の切り替え時)にsceDisplayWaitVBlankStart()で同期待ちをするので、ReadよりもPeekの方がよさそうですね。もっさりぃにちょっと効くかもしれません。

有益な情報をありがとうございました。
Posted by ひっそりぃ at 2009年09月29日 09:26
こちらこそ、詳細な情報をありがとうございます。
謎だった動作が判明しました。

キーの状態を取得するには、Peek
キー入力を待つ場合は、Read

と、使い分けると良いのではないかと思います。
Posted by at 2009年10月05日 20:58
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:


この記事へのトラックバック
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。