Home | History | Annotate | Download | only in win32
      1 /*
      2 The zlib/libpng License
      3 
      4 Copyright (c) 2005-2007 Phillip Castaneda (pjcast -- www.wreckedgames.com)
      5 
      6 This software is provided 'as-is', without any express or implied warranty. In no event will
      7 the authors be held liable for any damages arising from the use of this software.
      8 
      9 Permission is granted to anyone to use this software for any purpose, including commercial
     10 applications, and to alter it and redistribute it freely, subject to the following
     11 restrictions:
     12 
     13     1. The origin of this software must not be misrepresented; you must not claim that
     14 		you wrote the original software. If you use this software in a product,
     15 		an acknowledgment in the product documentation would be appreciated but is
     16 		not required.
     17 
     18     2. Altered source versions must be plainly marked as such, and must not be
     19 		misrepresented as being the original software.
     20 
     21     3. This notice may not be removed or altered from any source distribution.
     22 */
     23 #include "win32/Win32ForceFeedback.h"
     24 #include "OISException.h"
     25 #include <math.h>
     26 
     27 // 0 = No trace; 1 = Important traces; 2 = Debug traces
     28 #define OIS_WIN32_JOYFF_DEBUG 1
     29 
     30 #if (defined (_DEBUG) || defined(OIS_WIN32_JOYFF_DEBUG))
     31   #include <iostream>
     32   #include <sstream>
     33   using namespace std;
     34 #endif
     35 
     36 using namespace OIS;
     37 
     38 //--------------------------------------------------------------//
     39 Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps) :
     40   mHandles(0), mJoyStick(pDIJoy), mFFAxes(0), mpDIJoyCaps(pDIJoyCaps)
     41 {
     42 #if (OIS_WIN32_JOYFF_DEBUG > 0)
     43   cout << "FFSamplePeriod      : " << mpDIJoyCaps->dwFFSamplePeriod << " mu-s, "
     44 	   << "FFMinTimeResolution : " << mpDIJoyCaps->dwFFMinTimeResolution << " mu-s,"
     45 	   << "" << endl;
     46 #endif
     47 }
     48 
     49 //--------------------------------------------------------------//
     50 Win32ForceFeedback::~Win32ForceFeedback()
     51 {
     52 	//Get the effect - if it exists
     53 	for(EffectList::iterator i = mEffectList.begin(); i != mEffectList.end(); ++i )
     54 	{
     55 		LPDIRECTINPUTEFFECT dxEffect = i->second;
     56 		if( dxEffect )
     57 		{
     58 			dxEffect->Unload();
     59 			dxEffect->Release();
     60 		}
     61 	}
     62 
     63 	mEffectList.clear();
     64 }
     65 
     66 //--------------------------------------------------------------//
     67 short Win32ForceFeedback::getFFAxesNumber()
     68 {
     69 	return mFFAxes;
     70 }
     71 
     72 //--------------------------------------------------------------//
     73 unsigned short Win32ForceFeedback::getFFMemoryLoad()
     74 {
     75     DIPROPDWORD dipdw;  // DIPROPDWORD contains a DIPROPHEADER structure.
     76 	dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
     77 	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
     78 	dipdw.diph.dwObj        = 0; // device property
     79 	dipdw.diph.dwHow        = DIPH_DEVICE;
     80 	dipdw.dwData            = 0; // In case of any error.
     81 
     82 	const HRESULT hr = mJoyStick->GetProperty(DIPROP_FFLOAD, &dipdw.diph);
     83 	if(FAILED(hr))
     84 	{
     85 	    if (hr == DIERR_NOTEXCLUSIVEACQUIRED)
     86 		    OIS_EXCEPT(E_General, "Can't query FF memory load as device was not acquired in exclusive mode");
     87 		else
     88 		    OIS_EXCEPT(E_General, "Unknown error querying FF memory load ->..");
     89 	}
     90 
     91 	return (unsigned short)dipdw.dwData;
     92 }
     93 
     94 //--------------------------------------------------------------//
     95 void Win32ForceFeedback::upload( const Effect* effect )
     96 {
     97 	switch( effect->force )
     98 	{
     99 		case OIS::Effect::ConstantForce: _updateConstantEffect(effect);	break;
    100 		case OIS::Effect::RampForce: _updateRampEffect(effect);	break;
    101 		case OIS::Effect::PeriodicForce: _updatePeriodicEffect(effect);	break;
    102 		case OIS::Effect::ConditionalForce:	_updateConditionalEffect(effect); break;
    103 		//case OIS::Effect::CustomForce: _updateCustomEffect(effect); break;
    104 		default: OIS_EXCEPT(E_NotImplemented, "Requested Force not Implemented yet, sorry!"); break;
    105 	}
    106 }
    107 
    108 //--------------------------------------------------------------//
    109 void Win32ForceFeedback::modify( const Effect* eff )
    110 {
    111 	//Modifying is essentially the same as an upload, so, just reuse that function
    112 	upload(eff);
    113 }
    114 
    115 //--------------------------------------------------------------//
    116 void Win32ForceFeedback::remove( const Effect* eff )
    117 {
    118 	//Get the effect - if it exists
    119 	EffectList::iterator i = mEffectList.find(eff->_handle);
    120 	if( i != mEffectList.end() )
    121 	{
    122 		LPDIRECTINPUTEFFECT dxEffect = i->second;
    123 		if( dxEffect )
    124 		{
    125 			dxEffect->Stop();
    126 			//We care about the return value - as the effect might not
    127 			//have been unlaoded
    128 			if( SUCCEEDED(dxEffect->Unload()) )
    129 			{
    130 			    dxEffect->Release();
    131 				mEffectList.erase(i);
    132 			}
    133 		}
    134 		else
    135 			mEffectList.erase(i);
    136 	}
    137 }
    138 
    139 //--------------------------------------------------------------//
    140 void Win32ForceFeedback::setMasterGain( float level )
    141 {
    142 	//Between 0 - 10,000
    143 	int gain_level = (int)(10000.0f * level);
    144 
    145 	if( gain_level > 10000 )
    146 		gain_level = 10000;
    147 	else if( gain_level < 0 )
    148 		gain_level = 0;
    149 
    150 	DIPROPDWORD DIPropGain;
    151 	DIPropGain.diph.dwSize       = sizeof(DIPropGain);
    152 	DIPropGain.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    153 	DIPropGain.diph.dwObj        = 0;
    154 	DIPropGain.diph.dwHow        = DIPH_DEVICE;
    155 	DIPropGain.dwData            = gain_level;
    156 
    157 #if (OIS_WIN32_JOYFF_DEBUG > 0)
    158 	cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting master gain to "
    159 		 << level << " => " << DIPropGain.dwData << endl;
    160 #endif
    161 
    162 	const HRESULT hr = mJoyStick->SetProperty(DIPROP_FFGAIN, &DIPropGain.diph);
    163 
    164 #if defined (_DEBUG)
    165 	if(FAILED(hr))
    166 	    cout << "Failed to change master gain" << endl;
    167 #endif
    168 }
    169 
    170 //--------------------------------------------------------------//
    171 void Win32ForceFeedback::setAutoCenterMode( bool auto_on )
    172 {
    173 	DIPROPDWORD DIPropAutoCenter;
    174 	DIPropAutoCenter.diph.dwSize       = sizeof(DIPropAutoCenter);
    175 	DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    176 	DIPropAutoCenter.diph.dwObj        = 0;
    177 	DIPropAutoCenter.diph.dwHow        = DIPH_DEVICE;
    178 	DIPropAutoCenter.dwData            = (auto_on ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF);
    179 
    180 #if (OIS_WIN32_JOYFF_DEBUG > 0)
    181 	cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting auto-center mode to "
    182 		 << auto_on << " => " << DIPropAutoCenter.dwData << endl;
    183 #endif
    184 
    185 	const HRESULT hr = mJoyStick->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
    186 
    187 #if defined (_DEBUG)
    188 	if(FAILED(hr))
    189 	    cout << "Failed to change auto-center mode" << endl;
    190 #endif
    191 }
    192 
    193 //--------------------------------------------------------------//
    194 void Win32ForceFeedback::_updateConstantEffect( const Effect* effect )
    195 {
    196 	ConstantEffect *eff = static_cast<ConstantEffect*>(effect->getForceEffect());
    197 
    198 	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    199 	LONG            rglDirection[2] = { 0, 0 };
    200 	DIENVELOPE      diEnvelope;
    201 	DICONSTANTFORCE cf;
    202 	DIEFFECT        diEffect;
    203 
    204 	//Currently only support 1 axis
    205 	//if( effect->getNumAxes() == 1 )
    206 	cf.lMagnitude = eff->level;
    207 
    208 #if (OIS_WIN32_JOYFF_DEBUG > 1)
    209 	cout << "  Level : " << eff->level
    210 		 << " => " << cf.lMagnitude << endl;
    211 #endif
    212 
    213 	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONSTANTFORCE), &cf, effect, &eff->envelope);
    214 	_upload(GUID_ConstantForce, &diEffect, effect);
    215 }
    216 
    217 //--------------------------------------------------------------//
    218 void Win32ForceFeedback::_updateRampEffect( const Effect* effect )
    219 {
    220 	RampEffect *eff = static_cast<RampEffect*>(effect->getForceEffect());
    221 
    222 	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    223 	LONG            rglDirection[2] = { 0, 0 };
    224 	DIENVELOPE      diEnvelope;
    225 	DIRAMPFORCE     rf;
    226 	DIEFFECT        diEffect;
    227 
    228 	//Currently only support 1 axis
    229 	rf.lStart = eff->startLevel;
    230 	rf.lEnd = eff->endLevel;
    231 
    232 	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIRAMPFORCE), &rf, effect, &eff->envelope );
    233 	_upload(GUID_RampForce, &diEffect, effect);
    234 }
    235 
    236 //--------------------------------------------------------------//
    237 void Win32ForceFeedback::_updatePeriodicEffect( const Effect* effect )
    238 {
    239 	PeriodicEffect *eff = static_cast<PeriodicEffect*>(effect->getForceEffect());
    240 
    241 	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    242 	LONG            rglDirection[2] = { 0, 0 };
    243 	DIENVELOPE      diEnvelope;
    244 	DIPERIODIC      pf;
    245 	DIEFFECT        diEffect;
    246 
    247 	//Currently only support 1 axis
    248 	pf.dwMagnitude = eff->magnitude;
    249 	pf.lOffset = eff->offset;
    250 	pf.dwPhase = eff->phase;
    251 	pf.dwPeriod = eff->period;
    252 
    253 	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIPERIODIC), &pf, effect, &eff->envelope );
    254 
    255 	switch( effect->type )
    256 	{
    257 	case OIS::Effect::Square: _upload(GUID_Square, &diEffect, effect); break;
    258 	case OIS::Effect::Triangle: _upload(GUID_Triangle, &diEffect, effect); break;
    259 	case OIS::Effect::Sine: _upload(GUID_Sine, &diEffect, effect); break;
    260 	case OIS::Effect::SawToothUp: _upload(GUID_SawtoothUp, &diEffect, effect); break;
    261 	case OIS::Effect::SawToothDown:	_upload(GUID_SawtoothDown, &diEffect, effect); break;
    262 	default: break;
    263 	}
    264 }
    265 
    266 //--------------------------------------------------------------//
    267 void Win32ForceFeedback::_updateConditionalEffect( const Effect* effect )
    268 {
    269 	ConditionalEffect *eff = static_cast<ConditionalEffect*>(effect->getForceEffect());
    270 
    271 	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    272 	LONG            rglDirection[2] = { 0, 0 };
    273 	DIENVELOPE      diEnvelope;
    274 	DICONDITION     cf;
    275 	DIEFFECT        diEffect;
    276 
    277 	cf.lOffset = eff->deadband;
    278 	cf.lPositiveCoefficient = eff->rightCoeff;
    279 	cf.lNegativeCoefficient = eff->leftCoeff;
    280 	cf.dwPositiveSaturation = eff->rightSaturation;
    281 	cf.dwNegativeSaturation = eff->leftSaturation;
    282 	cf.lDeadBand = eff->deadband;
    283 
    284 	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONDITION), &cf, effect, 0 );
    285 
    286 	switch( effect->type )
    287 	{
    288 	case OIS::Effect::Friction:	_upload(GUID_Friction, &diEffect, effect); break;
    289 	case OIS::Effect::Damper: _upload(GUID_Damper, &diEffect, effect); break;
    290 	case OIS::Effect::Inertia: _upload(GUID_Inertia, &diEffect, effect); break;
    291 	case OIS::Effect::Spring: _upload(GUID_Spring, &diEffect, effect); break;
    292 	default: break;
    293 	}
    294 }
    295 
    296 //--------------------------------------------------------------//
    297 void Win32ForceFeedback::_updateCustomEffect( const Effect* /*effect*/ )
    298 {
    299     //CustomEffect *eff = static_cast<CustomEffect*>(effect->getForceEffect());
    300     //
    301 	//DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    302 	//LONG            rglDirection[2] = { 0, 0 };
    303 	//DIENVELOPE      diEnvelope;
    304 	//DICUSTOMFORCE cf;
    305 	//DIEFFECT        diEffect;
    306 	//cf.cChannels = 0;
    307 	//cf.dwSamplePeriod = 0;
    308 	//cf.cSamples = 0;
    309 	//cf.rglForceData = 0;
    310 	//_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICUSTOMFORCE), &cf, effect, &eff->envelope);
    311 	//_upload(GUID_CustomForce, &diEffect, effect);
    312 }
    313 
    314 //--------------------------------------------------------------//
    315 void Win32ForceFeedback::_setCommonProperties(
    316 		DIEFFECT* diEffect, DWORD* rgdwAxes,
    317 		LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size,
    318 		LPVOID struct_type, const Effect* effect, const Envelope* envelope )
    319 {
    320 	ZeroMemory(diEffect, sizeof(DIEFFECT));
    321 
    322 	diEffect->dwSize                  = sizeof(DIEFFECT);
    323 	diEffect->dwFlags                 = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
    324 	diEffect->dwGain                  = DI_FFNOMINALMAX;
    325 
    326 	diEffect->dwTriggerButton         = DIEB_NOTRIGGER; // effect->trigger_button; // TODO: Conversion
    327 	diEffect->dwTriggerRepeatInterval = effect->trigger_interval;
    328 
    329 #if (OIS_WIN32_JOYFF_DEBUG > 1)
    330 	cout << "  Trigger :" << endl
    331 		 << "    Button   : " << effect->trigger_button
    332 		 << " => " << diEffect->dwTriggerButton << endl
    333 		 << "    Interval : " << effect->trigger_interval
    334 		 << " => " << diEffect->dwTriggerRepeatInterval << endl;
    335 #endif
    336 
    337 	diEffect->cAxes                   = 1; // effect->getNumAxes();
    338 	diEffect->rgdwAxes                = rgdwAxes;
    339 
    340 	diEffect->rglDirection            = rglDirection; // TODO: conversion from effect->direction
    341 
    342 #if (OIS_WIN32_JOYFF_DEBUG > 1)
    343 	cout << "  Direction : " << Effect::getDirectionName(effect->direction)
    344 		 << " => {";
    345 	for (int iDir=0; iDir < (int)diEffect->cAxes; iDir++)
    346 	  cout << " " << diEffect->rglDirection[iDir];
    347 	cout << "}" << endl;
    348 #endif
    349 
    350 	if (diEnvelope && envelope && envelope->isUsed())
    351 	{
    352 	    diEnvelope->dwSize = sizeof(DIENVELOPE);
    353 	    diEnvelope->dwAttackLevel = envelope->attackLevel;
    354 	    diEnvelope->dwAttackTime  = envelope->attackLength;
    355 	    diEnvelope->dwFadeLevel   = envelope->fadeLevel;
    356 	    diEnvelope->dwFadeTime    = envelope->fadeLength;
    357 	    diEffect->lpEnvelope = diEnvelope;
    358 	}
    359 	else
    360 	    diEffect->lpEnvelope = 0;
    361 
    362 #if (OIS_WIN32_JOYFF_DEBUG > 1)
    363 	if (diEnvelope && envelope && envelope->isUsed())
    364 	{
    365 		cout << "  Enveloppe :" << endl
    366 			 << "    AttackLen : " << envelope->attackLength
    367 			 << " => " << diEnvelope->dwAttackTime << endl
    368 			 << "    AttackLvl : " << envelope->attackLevel
    369 			 << " => " << diEnvelope->dwAttackLevel << endl
    370 			 << "    FadeLen   : " << envelope->fadeLength
    371 			 << " => " << diEnvelope->dwFadeTime << endl
    372 			 << "    FadeLvl   : " << envelope->fadeLevel
    373 			 << " => " << diEnvelope->dwFadeLevel << endl;
    374 	}
    375 #endif
    376 
    377 	diEffect->dwSamplePeriod          = 0;
    378 	diEffect->dwDuration              = effect->replay_length;
    379 	diEffect->dwStartDelay            = effect->replay_delay;
    380 
    381 #if (OIS_WIN32_JOYFF_DEBUG > 1)
    382 	cout << "  Replay :" << endl
    383 		 << "    Length : " << effect->replay_length
    384 		 << " => " << diEffect->dwDuration << endl
    385 		 << "    Delay  : " << effect->replay_delay
    386 		 << " => " << diEffect->dwStartDelay << endl;
    387 #endif
    388 
    389 	diEffect->cbTypeSpecificParams    = struct_size;
    390 	diEffect->lpvTypeSpecificParams   = struct_type;
    391 }
    392 
    393 //--------------------------------------------------------------//
    394 void Win32ForceFeedback::_upload( GUID guid, DIEFFECT* diEffect, const Effect* effect)
    395 {
    396 	LPDIRECTINPUTEFFECT dxEffect = 0;
    397 
    398 	//Get the effect - if it exists
    399 	EffectList::iterator i = mEffectList.find(effect->_handle);
    400 	//It has been created already
    401 	if( i != mEffectList.end() )
    402 		dxEffect = i->second;
    403 	else //This effect has not yet been created - generate a handle
    404 		effect->_handle = mHandles++;
    405 
    406 	if( dxEffect == 0 )
    407 	{
    408 		//This effect has not yet been created, so create it
    409 		HRESULT hr = mJoyStick->CreateEffect(guid, diEffect, &dxEffect, NULL);
    410 		if(SUCCEEDED(hr))
    411 		{
    412 			mEffectList[effect->_handle] = dxEffect;
    413 			dxEffect->Start(INFINITE,0);
    414 		}
    415 		else if( hr == DIERR_DEVICEFULL )
    416 			OIS_EXCEPT(E_DeviceFull, "Remove an effect before adding more!");
    417 		else
    418 			OIS_EXCEPT(E_General, "Unknown error creating effect->..");
    419 	}
    420 	else
    421 	{
    422 		//ToDo -- Update the Effect
    423 		HRESULT hr = dxEffect->SetParameters( diEffect, DIEP_DIRECTION |
    424 			DIEP_DURATION | DIEP_ENVELOPE | DIEP_STARTDELAY | DIEP_TRIGGERBUTTON |
    425 			DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS | DIEP_START );
    426 
    427 		if(FAILED(hr)) OIS_EXCEPT(E_InvalidParam, "Error updating device!");
    428 	}
    429 }
    430 
    431 //--------------------------------------------------------------//
    432 void Win32ForceFeedback::_addEffectSupport( LPCDIEFFECTINFO pdei )
    433 {
    434 #if (OIS_WIN32_JOYFF_DEBUG > 0)
    435     // Dump some usefull information about the effect type.
    436     cout << "Adding support for '" << pdei->tszName << "' effect type" << endl;
    437 	cout << "  Supported static params: ";
    438 	if (pdei->dwStaticParams & DIEP_AXES) cout << " Axes";
    439 	if (pdei->dwStaticParams & DIEP_DIRECTION) cout << " Direction";
    440 	if (pdei->dwStaticParams & DIEP_DURATION) cout << " Duration";
    441 	if (pdei->dwStaticParams & DIEP_ENVELOPE) cout << " Envelope";
    442 	if (pdei->dwStaticParams & DIEP_GAIN) cout << " Gain";
    443 	if (pdei->dwStaticParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod";
    444 	if (pdei->dwStaticParams & DIEP_STARTDELAY) cout << " StartDelay";
    445 	if (pdei->dwStaticParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton";
    446 	if (pdei->dwStaticParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval";
    447 	if (pdei->dwStaticParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams";
    448 	cout << endl;
    449 	cout << "  Supported dynamic params: ";
    450 	if (pdei->dwDynamicParams & DIEP_AXES) cout << " Axes";
    451 	if (pdei->dwDynamicParams & DIEP_DIRECTION) cout << " Direction";
    452 	if (pdei->dwDynamicParams & DIEP_DURATION) cout << " Duration";
    453 	if (pdei->dwDynamicParams & DIEP_ENVELOPE) cout << " Envelope";
    454 	if (pdei->dwDynamicParams & DIEP_GAIN) cout << " Gain";
    455 	if (pdei->dwDynamicParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod";
    456 	if (pdei->dwDynamicParams & DIEP_STARTDELAY) cout << " StartDelay";
    457 	if (pdei->dwDynamicParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton";
    458 	if (pdei->dwDynamicParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval";
    459 	if (pdei->dwDynamicParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams";
    460 	cout << endl;
    461 	cout << "  More details about supported parameters support: ";
    462 	if (pdei->dwEffType & DIEFT_STARTDELAY) cout << " StartDelay";
    463 	if (pdei->dwEffType & DIEFT_FFATTACK) cout << " Attack";
    464 	if (pdei->dwEffType & DIEFT_FFFADE) cout << " Fade";
    465 	if (pdei->dwEffType & DIEFT_DEADBAND) cout << " DeadBand";
    466 	if (pdei->dwEffType & DIEFT_SATURATION) cout << " Saturation";
    467 	if (pdei->dwEffType & DIEFT_POSNEGSATURATION) cout << " PosNegaturation";
    468 	if (pdei->dwEffType & DIEFT_POSNEGCOEFFICIENTS) cout << " PosNegCoefficients";
    469 	if (pdei->dwEffType & DIEFT_HARDWARE) cout << " HardwareSpecific";
    470 	cout << endl;
    471 #endif
    472 
    473     Effect::EForce eForce;
    474 	switch (DIEFT_GETTYPE(pdei->dwEffType))
    475 	{
    476 	    case DIEFT_CONSTANTFORCE:
    477 		    eForce = Effect::ConstantForce;
    478 			break;
    479 	    case DIEFT_RAMPFORCE:
    480 		    eForce = Effect::RampForce;
    481 			break;
    482 	    case DIEFT_PERIODIC:
    483 		    eForce = Effect::PeriodicForce;
    484 			break;
    485 	    case DIEFT_CONDITION:
    486 		    eForce = Effect::ConditionalForce;
    487 			break;
    488 	    case DIEFT_CUSTOMFORCE:
    489 		    eForce = Effect::CustomForce;
    490 			break;
    491 	    default:
    492 		    eForce = Effect::UnknownForce;
    493 #if defined (_DEBUG)
    494 			cout << "Win32ForceFeedback: DirectInput8 Effect type support not implemented: "
    495 				 << "DIEFT_GETTYPE="<< (int)DIEFT_GETTYPE(pdei->dwEffType) << endl;
    496 #endif
    497 			return;
    498 	}
    499 
    500 	//Determine what the effect type is and how it corresponds to our OIS's Enums
    501 	//We could save the GUIDs too, however, we will just use the predefined ones later
    502 	if( pdei->guid == GUID_ConstantForce )
    503 		_addEffectTypes(eForce, Effect::Constant );
    504 	else if( pdei->guid == GUID_Triangle )
    505 		_addEffectTypes(eForce, Effect::Triangle );
    506 	else if( pdei->guid == GUID_Spring )
    507 		_addEffectTypes(eForce, Effect::Spring );
    508 	else if( pdei->guid == GUID_Friction )
    509 		_addEffectTypes(eForce, Effect::Friction );
    510 	else if( pdei->guid == GUID_Square )
    511 		_addEffectTypes(eForce, Effect::Square );
    512 	else if( pdei->guid == GUID_Sine )
    513 		_addEffectTypes(eForce, Effect::Sine );
    514 	else if( pdei->guid == GUID_SawtoothUp )
    515 		_addEffectTypes(eForce, Effect::SawToothUp );
    516 	else if( pdei->guid == GUID_SawtoothDown )
    517 		_addEffectTypes(eForce, Effect::SawToothDown );
    518 	else if( pdei->guid == GUID_Damper )
    519 		_addEffectTypes(eForce, Effect::Damper );
    520 	else if( pdei->guid == GUID_Inertia )
    521 		_addEffectTypes(eForce, Effect::Inertia );
    522 	else if( pdei->guid == GUID_CustomForce )
    523 		_addEffectTypes(eForce, Effect::Custom );
    524 	else if( pdei->guid == GUID_RampForce )
    525 		_addEffectTypes(eForce, Effect::Ramp );
    526 
    527 #if defined (_DEBUG)
    528 	//Only care about this for Debugging Purposes
    529 	//else
    530 	//{
    531 	//	std::ostringstream ss;
    532 	//	ss << "Win32ForceFeedback, DirectInput8 Effect not found. Reported as: "
    533 	//	   << pdei->tszName;
    534 	//	OIS_EXCEPT( E_General, ss.str().c_str());
    535 	//}
    536 #endif
    537 }
    538 
    539 //--------------------------------------------------------------//
    540 void Win32ForceFeedback::_addFFAxis()
    541 {
    542 	mFFAxes++;
    543 }
    544