2012-09-16

WindowsApp XInput GamePad Visual Cpp

[Windows] Xbox 360 Controllerを認識する簡単なWindowsアプリをVisual C++ 2008 で作る

動作確認環境:

  • Windows7 64bit
  • Visual C++ 2008 Express
  • DirectX SDK (2010 June)

Intro

FlashでGamePadを使ったゲームを作ってみたい。Flashは「今後はGameに力を入れる!」と言いながらGamePadに対応していないのだが‥

  • Adobe AIRを使えば、Windowsで動作するexeファイルを作れるらしい。
  • ANE という技術使えば WindowsのDLLと連携できるので、AIRからKinectなど使えるらしい。

Kinectが使えるくらいなら、GamePadも使えるだろう。とりあえずGamePadを認識するWindowsのプログラムを作成してみる。

今どきの海外PCゲームはXbox 360 ControllerのGamePad形式(XInput)に対応しているものが多いようだ。XInput対応について調べてみたが、Win32APIではだめな様子。DirectX開発環境入れればXInput対応できるらしい。

Visual C# + .Net使うと簡単らしいのだが、.Net Frameworkランタイム入れなくてはならないという依存関係は好きではない。なるべくそういう面倒なことをしなくてすむように、Visual C++ で作成したい。

Prepare

以下をダウンロードして、インストールした。

  • Visual C++ 2008 Express
  • DirectX SDK (2010 June)

DirectX SDK入れたら、Visual C++の[ツール - オプション - プロジェクト - VC++ディレクトリ] のインクルードとライブラリに、 C:\Program Files\Microsoft DirectX SDK (June 2010)\Include などが自動的に追加されていた。

Build sample

ここのサンプルをビルドしてみた。

http://www.codeproject.com/Articles/26949/Xbox-360-Controller-Input-in-C-with-XInput

[ファイル - 開く - プロジェクト/ソリューション] で slnファイルを開く。

[ビルド - ソリューションのリビルド] でexeを作成して、実行。「サイド バイ サイド構成が正しくないため、アプリケーションを開始できませんでした」というエラー。解決法としては「Visual C++ 再頒布可能パッケージ」を入れればよいらしいのだが、そういったものを入れたくないからこそVisualC++をさわっているのである。

解決法はこちらにあった。

静的にリンクする

Cランタイムライブラリについては、プロジェクトのプロパティの[C/C++]-[コード生成]-[ランタイムライブラリ]で(/MDの代わりに)/MTを選ぶ。

http://d.hatena.ne.jp/teematsu/20091015/1255618138

これでOK。振動を確認。

少しmain.cppを編集して試した。

/* The Code Project Open License (CPOL) 1.02 */
/* http://www.codeproject.com/Articles/26949/Xbox-360-Controller-Input-in-C-with-XInput */
#include "CXBOXController.h"
#include <iostream>

CXBOXController* Player1;
int main(int argc, char* argv[])
{
    Player1 = new CXBOXController(1);

    std::cout << "Instructions:\n";
    std::cout << "[A] Vibrate Left Only\n";
    std::cout << "[B] Vibrate Right Only\n";
    std::cout << "[X] Vibrate Both\n";
    std::cout << "[Y] Vibrate Neither\n";
    std::cout << "[→] Vibrate Left Only\n";
    std::cout << "[←] Vibrate Right Only\n";
    std::cout << "[L THUMB] Vibrate Both\n";
    std::cout << "[R1] Vibrate Neither\n";
    std::cout << "[BACK] Exit\n";

    while(true){
        if(! Player1->IsConnected() ) {
            std::cout << "\n\tERROR! PLAYER 1 - XBOX 360 Controller Not Found!\n";
            std::cout << "Press Any Key To Exit.";
            std::cin.get();
            break;
        } else {

            if(Player1->GetState().Gamepad.wButtons & XINPUT_GAMEPAD_A)
                Player1->Vibrate(65535, 0);

            if(Player1->GetState().Gamepad.wButtons & XINPUT_GAMEPAD_B)
                Player1->Vibrate(0, 65535);

            if(Player1->GetState().Gamepad.wButtons & XINPUT_GAMEPAD_X)
                Player1->Vibrate(65535, 65535);

            if(Player1->GetState().Gamepad.wButtons & XINPUT_GAMEPAD_Y)
                Player1->Vibrate();

            if(Player1->GetState().Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
                Player1->Vibrate(20000, 0);

            if(Player1->GetState().Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
                Player1->Vibrate(0, 20000);

            if(Player1->GetState().Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB)
                Player1->Vibrate(20000, 20000);

            if(Player1->GetState().Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER)
                Player1->Vibrate();

            if(Player1->GetState().Gamepad.wButtons & XINPUT_GAMEPAD_BACK)
                break;
        }
    } //while
    delete(Player1);
    return( 0 );
}

XINPUT_GAMEPAD_LEFT_THUMB というのは左アナログスティックを上から押し込むこと。

XINPUT_GAMEPAD_RIGHT_SHOULDER というのは http://en.wikipedia.org/wiki/File:360_controller.svg でいう Right Bumper。RB。プレステのコントローラーでいう R1。

ここまでで「デジタル ボタン」の認識方法はわかってきた。しかし「アナログ スティック・ボタン」の認識方法がわからない。

→ Microsoft公式の http://msdn.microsoft.com/ja-jp/library/bb173050(v=vs.85).aspx 見るとサンプルにあるらしい。

Windowsの[Start - DirectX SDK - サンプル ブラウザー] でインストールできた。確かに動作したぞ。これをDLL化して、ANEでFlashに接続すればいいのか。

ANEもAIRもわからないことが多い。そもそもObject Orientedもよくわかってないし‥‥最初は入門書から行こうか。

0 件のコメント:

コメントを投稿

人気記事