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 //--------------------------------------------------------------//
Win32ForceFeedback(IDirectInputDevice8 * pDIJoy,const DIDEVCAPS * pDIJoyCaps)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 //--------------------------------------------------------------//
~Win32ForceFeedback()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 //--------------------------------------------------------------//
getFFAxesNumber()67 short Win32ForceFeedback::getFFAxesNumber()
68 {
69 return mFFAxes;
70 }
71
72 //--------------------------------------------------------------//
getFFMemoryLoad()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 //--------------------------------------------------------------//
upload(const Effect * effect)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 //--------------------------------------------------------------//
modify(const Effect * eff)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 //--------------------------------------------------------------//
remove(const Effect * eff)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 //--------------------------------------------------------------//
setMasterGain(float level)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 //--------------------------------------------------------------//
setAutoCenterMode(bool auto_on)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 //--------------------------------------------------------------//
_updateConstantEffect(const Effect * effect)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 //--------------------------------------------------------------//
_updateRampEffect(const Effect * effect)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 //--------------------------------------------------------------//
_updatePeriodicEffect(const Effect * effect)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 //--------------------------------------------------------------//
_updateConditionalEffect(const Effect * effect)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 //--------------------------------------------------------------//
_updateCustomEffect(const Effect *)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 //--------------------------------------------------------------//
_setCommonProperties(DIEFFECT * diEffect,DWORD * rgdwAxes,LONG * rglDirection,DIENVELOPE * diEnvelope,DWORD struct_size,LPVOID struct_type,const Effect * effect,const Envelope * envelope)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 //--------------------------------------------------------------//
_upload(GUID guid,DIEFFECT * diEffect,const Effect * effect)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 //--------------------------------------------------------------//
_addEffectSupport(LPCDIEFFECTINFO pdei)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 //--------------------------------------------------------------//
_addFFAxis()540 void Win32ForceFeedback::_addFFAxis()
541 {
542 mFFAxes++;
543 }
544