WiiYourself!

導入

- WiiYourself! - gl.tter's native C++ Wiimote library.

Demo

ライブラリに同梱されているデモで、動作を確認できます。それにはまずWiiリモコンとPCとの接続を確立させ、ライブラリのDemo\Demo.exeを実行します。

サンプルのビルド

これのビルドにはWDK (DDK) が必要です。インストールされていないならば、まずこれを用意します。

このライブラリにはVirtual Studioのソリューションが用意されているため、それで簡単にビルドの確認をできます。DemoフォルダにVS2005とVS2008の2つのバージョン向けのDemo.slnがありますので、所有しているバージョンに合わせて適切な方を開きます。そしてビルドします。そのときWDKへのパスが設定されていないと、次のようエラーとなります。

wiimote.cpp(28) : fatal error C1083: include ファイルを開けません。'hidsdi.h': No such file or directory
LINK : fatal error LNK1104: ファイル 'hid.lib' を開くことができません。

この場合にはそれぞれのパスを設定します。Visual Studioのオプションを開き、[プロジェクトおよびソリューション]の[VC++ ディレクトリ]でディレクトリを表示するプロジェクトに[インクルード ファイル]を選択し、たとえばWDK 8.1ならば%PROGRAMFILES(X86)%\Windows Kits\8.1\Include\sharedを追加します。このときこれを末尾に追加すると、

hidsdi.h(34) : error C2059: 構文エラー : 'return'
hidpi.h(310) : error C2146: 構文エラー : ';' が、識別子 '_IRQL_requires_max_' の前に必要です。
hidpi.h(310) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
…

のようにエラーとなるため、最初にインクルードされるようにリストの先頭へ移動します。visual c++ - WDK (Windows Driver Kit) and VC++ headers problem - Stack Overflow

次にhid.libが読み込まれるように、[ライブラリ ファイル]に、たとえば%PROGRAMFILES(X86)%\Windows Kits\8.1\Lib\winv6.3\um\x86を追加します。

ビルドが成功したら実行してみます。

実行時のエラー
音声ファイルの取得の失敗

実行時に「WiiYourself! : * couldn't get filesize for '1kSine16 (3130).raw' *」のようにエラーとなるときには、Demoフォルダにある拡張子がrawとwavの4つのファイルを、その実行方法に応じてソリューションのDemo.slnまたはビルドにより生成されたDemo.exeと同一フォルダにコピーします。なお、これらはサンプルの音声ファイルです。

アサーションの失敗

プロジェクトの設定でSDLチェックが有効になっていると、wiimote.cppの411行目のアサーションに失敗します。

サンプルコード

加速度センサーの値のみを取得する、簡単な方法を示します。

#include "wiimote.h"

void on_state_change(wiimote &remote, state_change_flags changed, const wiimote_state &new_state)
{
    if (changed & CONNECTED ) // 接続した
    {
        // ボタンか加速度に変化があったときに通知するように設定する
        remote.SetReportType(wiimote::IN_BUTTONS_ACCEL);
    }

    if (changed & ACCEL_CHANGED) // 加速度が変化した
    {
        printf("X:%+2.3f Y:%+2.3f Z:%+2.3f\r\n",
            remote.Acceleration.X,
            remote.Acceleration.Y,
            remote.Acceleration.Z);
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    wiimote remote;

    // コールバックを設定する
    remote.ChangedCallback = on_state_change;
    remote.CallbackTriggerFlags = (state_change_flags)(CONNECTED | ACCEL_CHANGED);

    // 接続する
    remote.Connect(wiimote::FIRST_AVAILABLE);

    // ホームボタンが押されるまでくり返す
    while (!remote.Button.Home())
    {
        // 情報を更新する
        while (remote.RefreshState() == NO_CHANGE) Sleep(1);
    }
    remote.Disconnect();

    return 0;
}