続 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コンだけなので、今回はこれで終わり。