ジョイスティックで入力しよう

1. ジョイスティックがつながっているか

ジョイスティックがつながっているかどうかは次のようなコードで調べることができます。

JOYINFO joyinfo;
UINT wNumDevs, wDeviceID;
BOOL bDev1Attached, bDev2Attached;
 
    if((wNumDevs = joyGetNumDevs()) == 0)
        return -1;   // ドライバーがない

    bDev1Attached = joyGetPos(JOYSTICKID1,&joyinfo) != JOYERR_UNPLUGGED;
    bDev2Attached = wNumDevs == 2 && joyGetPos(JOYSTICKID2,&joyinfo) != JOYERR_UNPLUGGED;

    if(bDev1Attached || bDev2Attached)   // どのjoysticIDを使うか決定する
        wDeviceID = bDev1Attached ? JOYSTICKID1 : JOYSTICKID2;
    else
        return -2;   // joystickがつながってない

このようなコードを初期化時に実行すればジョイスティックがどのように使えるか知ることができます。
上のコードでは関数 joyGetNumDevs と joyGetPos が使われています。
この2つは mmsystem.h で宣言されており、 winmm.lib をリンクして使います。

2. ジョイスティックの状態を取得する

ジョイスティックのボタンや方向キーの状態を取得するには、次のようにします。

JOYINFO joyinfo;
UINT wDeviceID = JOYSTICKID1;

    MMRESULT r=joyGetPos(wDeviceID,&joyinfo);
    if(r==JOYERR_NOERROR)
    {
        // ボタン
        if(joyinfo.wButtons & JOY_BUTTON1)
        {
            MessageBox(0,"ボタン1が押されました","",MB_OK);
        }
        if(joyinfo.wButtons & JOY_BUTTON2)
        {
            MessageBox(0,"ボタン2が押されました","",MB_OK);
        }
        
        // 方向キー
        if(joyinfo.wXpos>0xbfff)
        {
            MessageBox(0,"右キーが押されました","",MB_OK);
        }
        if(joyinfo.wXpos<0x3fff)
        {
            MessageBox(0,"左キーが押されました","",MB_OK);
        }
    }

JOYINFO 構造体

JOYINFO 構造体はジョイスティックの座標とボタン状態についての情報を持っています。
typedef struct { 
    UINT wXpos; 
    UINT wYpos; 
    UINT wZpos; 
    UINT wButtons; 
} JOYINFO; 
メンバ

wXpos
  X座標
wYpos
  Y座標
wZpos
  Z座標
wButtons
  以下に示す値を組み合わせたボタン状態
  JOY_BUTTON1  ボタン1が押されている (値: 0x0001)
  JOY_BUTTON2  ボタン2が押されている (値: 0x0002)
  JOY_BUTTON3  ボタン3が押されている (値: 0x0004)
  JOY_BUTTON4  ボタン4が押されている (値: 0x0008)

joyGetPos 関数

joyGetPos 関数は、座標とボタン状態を取得します。
MMRESULT joyGetPos(
  UINT uJoyID,  
  LPJOYINFO pji 
);
引数

uJoyID
  情報を取りたいジョイスティックのID (JOYSTICKID1 or JOYSTICKID2)
pji
  JOYINFO構造体へのポインタ

戻り値

成功した場合は JOYERR_NOERR を返します。エラーの場合は以下の値を返します。
MMSYSERR_NODRIVER  ジョイスティックのドライバーが存在しません。
MMSYSERR_INVALPARAM  不正な引数が渡されました。
JOYERR_UNPLUGGED  指定されたジョイスティックはつながっていません。

3. ジョイスティックのメッセージを受け取る

ジョイスティックのボタンや方向キーのメッセージを受け取るためには、まずジョイスティックをウインドウにキャプチャします。次のコードはメッセージハンドラの一部です。

case WM_CREATE: 
    if(joySetCapture(hWnd, JOYSTICKID1, NULL, FALSE)) 
    { 
        MessageBeep(MB_ICONEXCLAMATION); 
        MessageBox(hWnd, "Couldn't capture the joystick.", NULL, 
            MB_OK | MB_ICONEXCLAMATION); 
        PostMessage(hWnd,WM_CLOSE,0,0L); 
    } 
    break; 

ジョイスティックのメッセージは MM_JOY1MOVE, MM_JOY1BUTTONDOWN, MM_JOY1BUTTONUP があります。
2番目のジョイスティックのメッセージは MM_JOY2MOVE, MM_JOY2BUTTONDOWN, MM_JOY2BUTTONUP です。

MM_JOY1BUTTONDOWN メッセージ

MM_JOY1BUTTONDOWN メッセージは、ジョイスティック1のボタンが押されたことを知らせます。
MM_JOY1BUTTONDOWN 
fwButtons = wParam; 
xPos = LOWORD(lParam); 
yPos = HIWORD(lParam); 
パラメータ

fwButtons
  どのボタンの状態が変わり、どのボタンが押されているのかを識別します。次のうちのどれか1つです
  JOY_BUTTON1CHG  ボタン1の状態が変化した
  JOY_BUTTON2CHG  ボタン2の状態が変化した
  JOY_BUTTON3CHG  ボタン3の状態が変化した
  JOY_BUTTON4CHG  ボタン4の状態が変化した

  そして次の値の組み合わせです
  JOY_BUTTON1  ボタン1が押されている
  JOY_BUTTON2  ボタン2が押されている
  JOY_BUTTON3  ボタン3が押されている
  JOY_BUTTON4  ボタン4が押されている
xPos
  ジョイスティックのx座標です。
yPos
  ジョイスティックのy座標です。