古の技術でゲームプログラミング 第11回

 

ゲームでの操作といえばやっぱりゲームパッド!

ってことでゲームパッドの情報取得の方法です。

 

 

  デバイス情報の取得

 

PCにおいてゲームパッドは標準装備とはいいがたいので、そもそも接続してるかどうかの確認が必要です。

また、パッドの種類もいっぱいでボタンの数もちがったり結構メンドクサイです。

 

ってことでまずはデバイス情報を取得します。

 

MMRESULT joyGetDevCaps(
  UINT      uJoyID,
  LPJOYCAPS pjc,
  UINT      cbjc
);

これがゲームパッドのデバイス情報を取得するAPIです。

公式の解説を見るとuJoyIDは1~15の範囲みたいに書いてて意味不明ですが実際にはたぶん0~15です。

SDK上はJOYSTICKID1(0), JOYSTICKID2(1)の定義があるのでそのあたりを使えばいいだろう。

 

pjcにはJOYCAPS構造体(後述)のアドレスを渡す。

 

cbjcにはJOYCAPS構造体のサイズを渡す。

 

 

本来はuJoyID 0~15のデバイスをチェックして有効なやつをリスト化してユーザーサイドに使用するデバイスを選択してもらうような作りが理想的なんだろうけど、さすがにめんどくさすぎてやりたくない。

 

なのでJOYSTICKID1だけの対応にしちゃおう。

 

で、このAPIのリターンがJOYERR_NOERRORだったら使えるデバイスと判断してOK。

 

 

[JOYCAPS構造体]

typedef struct joycaps_tag {
  WORD wMid;
  WORD wPid;
  char szPname[MAXPNAMELEN];
  UINT wXmin;
  UINT wXmax;
  UINT wYmin;
  UINT wYmax;
  UINT wZmin;
  UINT wZmax;
  UINT wNumButtons;
  UINT wPeriodMin;
  UINT wPeriodMax;
  UINT wRmin;
  UINT wRmax;
  UINT wUmin;
  UINT wUmax;
  UINT wVmin;
  UINT wVmax;
  UINT wCaps;
  UINT wMaxAxes;
  UINT wNumAxes;
  UINT wMaxButtons;
  char szRegKey[MAXPNAMELEN];
  char szOEMVxD[MAX_JOYSTICKOEMVXDNAME];
} JOYCAPS, *PJOYCAPS, *NPJOYCAPS, *LPJOYCAPS;

取得できる情報としてはこんな感じでいっぱい。

見たほうがよさそうなのは以下かな?

 ・X~Vの軸のmax, min ... 各軸の最大、最小値 (押されてるかどうかの判断に必要。たぶん)

 ・wNumButtons ... ボタンの数

 ・wNumAxes ... 軸の数

 ・wCaps ... R,U,V軸の対応有無

 

軸の有無とかボタンの有無を見てから入力状態を見ないと、押されてると誤認しそうで難しい。

なんせパッドを1個しかもってないからいろんなパターンを試すこともできない。まじムズイ。

 

 

 

  パッドの入力状態の取得

 

実際にパッドの入力状態を取得するAPIは以下。

 

MMRESULT joyGetPosEx(UINT uJoyID, LPJOYINFOEX pji);

uJoyIDにはjoyGetDevCapsに渡したのと同じ値を入れる。

 

pjiにはJOYINFOEX構造体のアドレスを渡すんだけど、構造体にはあらかじめ値を入れておく必要あり。

dwSizeにはJOYINFOEXのサイズを入れる。

dwFlagsには取得したい情報が何かを設定するんだけど、とりあえずJOY_RETURNALLを入れておけば大丈夫だと思う。

 

ちなみにこの関数はExが付かないjoyGetPosってのもあります。

ただこちらは対応しているボタン数や軸の数が少なすぎてあんまり使えない。

たしかファミコンレベルのボタン数しか取れない。

 

 

[JOYINFOEX構造体]

typedef struct joyinfoex_tag {
  DWORD dwSize;
  DWORD dwFlags;
  DWORD dwXpos;
  DWORD dwYpos;
  DWORD dwZpos;
  DWORD dwRpos;
  DWORD dwUpos;
  DWORD dwVpos;
  DWORD dwButtons;
  DWORD dwButtonNumber;
  DWORD dwPOV;
  DWORD dwReserved1;
  DWORD dwReserved2;
} JOYINFOEX;

Xpos~Vposには各軸の位置が入る。

アナログ入力したいなら各軸の最大、最小からうまく入力具合を判別しなきゃいけない。

デジタル的にON/OFFを判断したい場合もやっぱり最大、最小値をもとに入力状態を見る必要あり。

じゃないとずっと誤入力状態と認識しちゃう可能性あり。

本来は調整できるようにしておくべきなんだろうけど、さすがにそれはメンドクサイので、私は最大、最小のそれぞれ半分の位置を閾値にして超えてたらON、超えてなかったらOFFと判断するようにしてる。

とりあえず所有してるパッドならそれで問題なく動いてる。他のパッドでどうなるかは知らない。

 

dwButtonsには各Bit毎にボタンのON/OFF状態が入るので、Bit単位でチェックするように。

 

dwPOVには方向が入る。内容は角度 x 100で0~35900の範囲の値が入る。

私のゲームパッドだと十字キーがこいつに割当たってて、押してないとFFFFとかが入ってたかな。

あとは右=0, 上=9000, 左=18000, 下=27000みたいな感じ。

スティック系がPOVに割当たってるゲームパッドのことを考えるとこれもある程度範囲で判定したほうがいいだろう。

 

 

おしまい。