続 DirectInput ライブラリ構築 FFB編
・フォースフィードバックを使うにはDISCL_EXCLUSIVE(排他協調レベル)が必要である。
・DIPROPAUTOCENTER_OFFを設定しておくと、他のエフェクトが妨害されないらしい。
diProp.diph.dwSize = sizeof ( DIPROPDWORD ); diProp.diph.dwHeaderSize = sizeof ( DIPROPHEADER ); diProp.diph.dwHow = DIPH_DEVICE; diProp.diph.dwObj = 0; diProp.dwData = DIPROPAUTOCENTER_OFF; lpdiDevice->SetProperty ( DIPROP_AUTOCENTER, &diProp.diph );
・エフェクトを作成するために、対応しているエフェクトを列挙する。(EnumEffects)
この辺は適当に・・・。
BOOL WINAPI CDxJoyStick::DIEnumEffectsCallback ( LPCDIEFFECTINFO pdei, LPVOID pvRef )
{
vector<DIEFFECTINFO> *pvecEffectInfo = ( vector<DIEFFECTINFO>* ) pvRef;
pvecEffectInfo->push_back ( *pdei );
return DIENUM_CONTINUE;
}
・DIEFFECTINFO の tszName から、何のエフェクトが分かるっぽい。
(PS2コンでテストしたら、左モーターがConstantで右モーターがRamp って出た。)
・エフェクトを作成する前準備として、2+1つの構造体を設定しなきゃいけない。
DIENVELOPE diEnvelope; DIEFFECT diEffect; DIほにゃららFORCE
MSDNのサンプル通りに設定して、CreateEffect。
今回はPS2コンのバイブができればそれでいいので、ConstantForceとRampForceを作成。
Magnitudeが回転する強さ。-10000〜10000が指定できるみたいだけど、
手元のPS2コンはマイナス指定しても逆回転にならなかった。
diConstant.lMagnitude = 10000; diEffect.cbTypeSpecificParams = sizeof(diConstant); diEffect.lpvTypeSpecificParams = &diConstant; veclpEffect.push_back ( NULL ); vecnEffectType.push_back ( vecEffectInfo[k].dwEffType ); m_vecDevice[i]->CreateEffect( vecEffectInfo[k].guid, &diEffect, &veclpEffect[veclpEffect.size()-1], NULL);
上はConstantForceの例。
RampForceは、lStartとかlEndをいろいろ変えてもPS2の右モーターの回り方に変化がなかった。
後はトリガー設定してるなら押せば回るだろうし、トリガー設定してないのなら
lpEffect->Start ( 1, 0 );
とかで回り始める。止める時はStop()。(ソフト終了しても勝手に止まってた。)
で、少しはまったのがMagnitudeの変更。
回しながら(Startした後に)Magnitudeを変更しても、反映されない。
そこで、停止(Stop)→変更(SetParameters)→開始(Start)とすることで、体感的には回しながらの変更が実現できた。
変更は至って簡単で、DIEFFECTとDIほにゃららFORCEの実体を用意して、
初期化、DIEFFECTのdwSizeを設定、DIほにゃららFORCEを設定、
DIEFFECTのcbTypeSpecificParamsとlpvTypeSpecificParamsを設定して
SetParametersを呼び出すだけでOK。
DIEFFECT diEffect; DICONSTANTFORCE diCForce; ZeroMemory ( &diEffect, sizeof ( DIEFFECT ) ); diEffect.dwSize = sizeof ( DIEFFECT ); diCForce.lMagnitude = nMagnitude; diEffect.cbTypeSpecificParams = sizeof diCForce; diEffect.lpvTypeSpecificParams = &diCForce; //lpEffect->Stop ( ); lpEffect->SetParameters ( &diEffect, DIEP_TYPESPECIFICPARAMS ); //lpEffect->Start ( 1, 0 );
回ってる最中に変更する場合はStopとStartをコメントアウト。
GTフォースとかあればそっちの方のテストもできるんだけど
手元にあるのがPS2コンだけなので、今回はこれで終わり。