2017-05-12 16 views
2

は私がIDirectInputDevice8インタフェースを使用して直接入力デバイスにポーリングする呼び出しを遮断する遮断すると非を行う必要があります。MicrosoftのIDirectInputDevice8を使用してC++でジョイスティックコードを実装する方法は?

阻止行うには、Linuxで

、我々は使用選択例:私は設定しても https://msdn.microsoft.com/en-us/library/windows/desktop/ee417816(v=vs.85).aspx

:私はidirectinputdevice8インタフェースを使用して同じことを行うことができますどのように

while(::select(_jdev+1, &set, NULL, NULL, &tv) > 0) 
{ 
    if(::read(_jdev, &js, sizeof(js_event)) != sizeof(js_event)) 
    { 
     perror("Joystick : read error"); 
     return; 
    } 

    _handleEvent(js); 
} 

IDirectInputDevice8 :: SetEventNotification()、新しいデータをフェッチするたびにpoll()を呼び出す必要がありますが、これはwではありませんorkableソリューションは、CPUを回転させる原因となるためです。

どうすればこの問題を解決できますか?

***現時点では、私はジョイスティックデバイスからデータを検索、繰り返し、接続し、取得できます。私はブロッキングコールを実装していません。

が...ここに私の実験/テストコードです...構文エラー

#include <windows.h> 
#include <dinput.h> 
#include <stdio.h> 
#include <iostream> 
#include <sstream> 
#include "joystick.h" 


LPDIRECTINPUT8 di; 
HRESULT hr; 
LPDIRECTINPUTDEVICE8 joystick; 
DIDEVCAPS capabilities; 

BOOL CALLBACK 
enumCallback(const DIDEVICEINSTANCE* instance, VOID* context) 
{ 
    HRESULT hr; 
    hr = di->CreateDevice(instance->guidInstance, &joystick, NULL); 
    if (FAILED(hr)) { 
     return DIENUM_CONTINUE; 
    } 
    return DIENUM_STOP; 
} 

int JoyStickProp() 
{ 
    if (FAILED(hr = joystick->SetDataFormat(&c_dfDIJoystick2))) { 
     return hr; 
    } 
    if (FAILED(hr = joystick->SetCooperativeLevel(NULL, DISCL_EXCLUSIVE | 
     DISCL_FOREGROUND))) { 
     return hr; 
    } 
    capabilities.dwSize = sizeof(DIDEVCAPS); 
    if (FAILED(hr = joystick->GetCapabilities(&capabilities))) { 
     return hr; 
    } 
} 

HRESULT JoyStickPoll(DIJOYSTATE2 *js) 
{ 
    HRESULT  hr; 

    if (joystick == NULL) { 
     return S_OK; 
    } 

    // Poll the device to read the current state 
    hr = joystick->Poll(); 
    if (FAILED(hr)) { 
     hr = joystick->Acquire(); 
     while (hr == DIERR_INPUTLOST) { 
      hr = joystick->Acquire(); 
     } 

     if ((hr == DIERR_INVALIDPARAM) || (hr == DIERR_NOTINITIALIZED)) { 
      return E_FAIL; 
     } 

     // If another application has control of this device, return successfully. 
     // We'll just have to wait our turn to use the joystick. 
     if (hr == DIERR_OTHERAPPHASPRIO) { 
      return S_OK; 
     } 
    } 

    // Get the input's device state 
    if (FAILED(hr = joystick->GetDeviceState(sizeof(DIJOYSTATE2), js))) { 
     return hr; // The device should have been acquired during the Poll() 
    } 

    return S_OK; 
} 

int main() 
{ 


    // Create a DirectInput device 
    if (FAILED(hr = DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
     IID_IDirectInput8, (VOID**)&di, NULL))) { 
     return hr; 
    } 

    // Look for the first simple joystick we can find. 
    if (FAILED(hr = di->EnumDevices(DI8DEVCLASS_GAMECTRL, enumCallback, 
     NULL, DIEDFL_ATTACHEDONLY))) { 
     return hr; 
    } 
    // Make sure we got a joystick 
    if (joystick == NULL) { 
     printf("Joystick not found.\n"); 
     return E_FAIL; 
    } 

    JoyStickProp(); 
    DIJOYSTATE2 diState; 

    HANDLE ghWriteEvent; 
    // Create joystick event stuff here 
    ghWriteEvent = CreateEvent(
     NULL,    // default security attributes 
     FALSE,    // manual-reset event 
     FALSE,    // initial state is nonsignaled 
     TEXT("WriteEvent") // object name 
     ); 

    //makesure we can read fromt the joystick before waiting for an event 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
    JoyStickPoll(&diState); 
    printf("x axis %d", diState.lX); 
    printf("y axis %d", diState.lY); 
joystick->SetEventNotification(ghWriteEvent); 
    while (TRUE) { 

     DWORD dwResult = WaitForSingleObject(
      ghWriteEvent, // event handle 
      INFINITE); 

     switch (dwResult) { 
     case WAIT_OBJECT_0: 
      // Event 1 has been set. If the event was created as 
      // autoreset, it has also been reset. 
      int x = 0; 
      //ProcessInputEvent1(); 
      break; 
     } 
    } 
} 
+0

[下線を見る](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier)もしあれば本当に迷惑になるコンパイラの標準ライブラリ実装で定義されている '_handleEvent'または' _jdev'があなたのコードを越えています。 – user4581301

+0

これは、Windowsで達成したいものの例としてLinuxコードです... Windowsコードや現在の問題とは関係ありません。 –

+0

無関係。アンダースコアは、C++で特別な意味を持ち、C++標準によってレイアウトされています。ルールはLinuxかWindowsかにかかわらず同じです。結果のみが異なります。どのように使用するか注意してください。 – user4581301

答えて

1

IDirectInputDevice8::SetEventNotification()のためのMSDNドキュメントはあなたに関連するコードスニペットを与えるを無視してください。

CreateEvent()に電話し、返されたHANDLEを引数としてSetEventNotification()に渡す必要があります。状態が変化したときにイベントが通知されます。イベントが発生するのを待つことができます。そして、通知を受け取ったら、IDirectInputDevice8::GetDeviceState()を使用して新しい状態データを取得します。

すべての標準Wait Functionsは、イベントが通知されるのを待つために適用されます。

while (TRUE) { 

    dwResult = MsgWaitForMultipleObjects(2, ah, FALSE, INFINITE, QS_ALLINPUT); 
    switch (dwResult) { 
     case WAIT_OBJECT_0: 
      // Event 1 has been set. If the event was created as 
      // autoreset, it has also been reset. 
      ProcessInputEvent1(); 
      break; 

IDirectInputDevice8::Poll()メソッドがイベントの通知を生成していないデバイスのために使用されます。次のコードスニペットは、MsgWaitForMultipleObjects()を使用して、あなたに1つの方法を示しています。彼らは彼らがあなたが望む方法を操作することができないので、あなたはそれらをポーリングすることになっています。

一部のジョイスティックや他のゲームデバイス、またはそれらの特定のオブジェクトは、do not generate hardware interrupts and do not return any data or signal any events until you call the IDirectInputDevice8::Poll methodです。

通知は、デバイスで通知が機能しない場合にのみ必要です。上記のリンクは、ポーリングが必要かどうかを特定する方法を説明しています。

+0

私はこれを行いました。私が間違っていない限り、ポーリングを呼び出すまでイベントは呼び出されません。私がやりたいこと、そして何が起こるべきかは、状態変化のイベントを待ってから投票を呼び出すことです。 –

+0

私はちょうど私がイベントとそれを実行するための別のスレッドを作成したことに気が付いた..多分それは物事を投げている..私はあなたに戻ってみてみましょう –

+2

@lukesignh: 'CreateEvent()'で作成されたイベントは特定のスレッドに結びついています。 1つまたは複数のスレッドは、別のスレッドがそのイベントを通知している間にイベントを待機することができます。だからあなたの問題ではありません。あなたの質問を編集して、あなたにとってうまくいかない実際のコードを表示してください。 –

関連する問題