Changeset 5695 for code/trunk/src/ois
- Timestamp:
- Aug 30, 2009, 2:22:00 AM (15 years ago)
- Location:
- code/trunk
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/resource2 (added) merged: 3373-3374,5594,5597,5610-5611,5614,5624,5641,5644-5646,5650-5664,5667-5672,5682-5684,5688-5691,5694
- Property svn:mergeinfo changed
-
code/trunk/src/ois/OISEffect.cpp
r1505 r5695 29 29 //Perhaps a case of a crazy extreme optimizer :/ (moved to header) 30 30 //const unsigned int Effect::OIS_INFINITE = 0xFFFFFFFF; 31 32 //------------------------------------------------------------------------------// 33 static const char* pszEForceString[] = 34 { "UnknownForce", 35 "ConstantForce", 36 "RampForce", 37 "PeriodicForce", 38 "ConditionalForce", 39 "CustomForce" }; 40 41 const char* Effect::getForceTypeName(Effect::EForce eValue) 42 { 43 return (eValue >= 0 && eValue < _ForcesNumber) ? pszEForceString[eValue] : "<Bad force type>"; 44 } 45 46 static const char* pszETypeString[] = 47 { "Unknown", 48 "Constant", 49 "Ramp", 50 "Square", "Triangle", "Sine", "SawToothUp", "SawToothDown", 51 "Friction", "Damper", "Inertia", "Spring", 52 "Custom" }; 53 54 const char* Effect::getEffectTypeName(Effect::EType eValue) 55 { 56 return (eValue >= 0 && eValue < _TypesNumber) ? pszETypeString[eValue] : "<Bad effect type>"; 57 } 58 59 static const char* pszEDirectionString[] = 60 { "NorthWest", "North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West"}; 61 62 const char* Effect::getDirectionName(Effect::EDirection eValue) 63 { 64 return (eValue >= 0 && eValue < _DirectionsNumber) ? pszEDirectionString[eValue] : "<Bad direction>"; 65 } 31 66 32 67 //------------------------------------------------------------------------------// -
code/trunk/src/ois/OISEffect.h
r1505 r5695 60 60 PeriodicForce, 61 61 ConditionalForce, 62 CustomForce 62 CustomForce, 63 _ForcesNumber // Always keep in last position. 63 64 }; 65 66 static const char* getForceTypeName(EForce eValue); 64 67 65 68 //! Type of effect … … 79 82 Inertia, //ConditionalForce 80 83 Spring, //ConditionalForce 81 Custom //CustomForce 84 Custom, //CustomForce 85 _TypesNumber // Always keep in last position. 82 86 }; 87 88 static const char* getEffectTypeName(EType eValue); 83 89 84 90 //! Direction of the Force … … 92 98 South, 93 99 SouthWest, 94 West 100 West, 101 _DirectionsNumber // Always keep in last position. 95 102 }; 103 104 static const char* getDirectionName(EDirection eValue); 96 105 97 106 /** … … 168 177 An optional envelope to be applied to the start/end of an effect. If any of 169 178 these values are nonzero, then the envelope will be used in setting up the 170 effect. Not currently utilised.. But, will be soon.179 effect. 171 180 */ 172 181 class _OISExport Envelope : public ForceEffect … … 178 187 #pragma warning (disable : 4800) 179 188 #endif 180 bool isUsed() { return attackLength | attackLevel | fadeLength | fadeLevel; }189 bool isUsed() const { return attackLength | attackLevel | fadeLength | fadeLevel; } 181 190 #if defined(OIS_MSVC_COMPILER) 182 191 #pragma warning (pop) 183 192 #endif 184 193 185 unsigned short attackLength; 194 // Duration of the attack (microseconds) 195 unsigned int attackLength; 196 197 // Absolute level at the beginning of the attack (0 to 10K) 198 // (automatically signed when necessary by FF core according to effect level sign) 186 199 unsigned short attackLevel; 187 unsigned short fadeLength; 200 201 // Duration of fade (microseconds) 202 unsigned int fadeLength; 203 204 // Absolute level at the end of fade (0 to 10K) 205 // (automatically signed when necessary by FF core according to effect level sign) 188 206 unsigned short fadeLevel; 189 207 }; … … 211 229 RampEffect() : startLevel(0), endLevel(0) {} 212 230 213 class Envelope envelope; //Optional env olope231 class Envelope envelope; //Optional envelope 214 232 signed short startLevel; //-10K to +10k 215 233 signed short endLevel; //-10K to +10k -
code/trunk/src/ois/OISForceFeedback.cpp
r1505 r5695 27 27 28 28 //-------------------------------------------------------------// 29 void ForceFeedback::_addEffectTypes( Effect::EForce force, Effect::EType type)29 ForceFeedback::ForceFeedback() : mSetGainSupport(false), mSetAutoCenterSupport(false) 30 30 { 31 if( force == Effect::UnknownForce || type == Effect::Unknown )32 OIS_EXCEPT( E_General, "Unknown Force||Type was added too effect list..." );33 34 mSupportedEffects[force] = type;35 31 } 36 32 37 33 //-------------------------------------------------------------// 38 const ForceFeedback::SupportedEffectList& 39 ForceFeedback::getSupportedEffects() const 34 void ForceFeedback::_addEffectTypes( Effect::EForce force, Effect::EType type ) 35 { 36 if( force <= Effect::UnknownForce || force >= Effect::_ForcesNumber 37 || type <= Effect::Unknown || type >= Effect::_TypesNumber ) 38 OIS_EXCEPT( E_General, "Can't add unknown effect Force/Type to the supported list" ); 39 40 mSupportedEffects.insert(std::pair<Effect::EForce, Effect::EType>(force, type)); 41 } 42 43 //-------------------------------------------------------------// 44 void ForceFeedback::_setGainSupport( bool on ) 45 { 46 mSetGainSupport = on; 47 } 48 49 //-------------------------------------------------------------// 50 void ForceFeedback::_setAutoCenterSupport( bool on ) 51 { 52 mSetAutoCenterSupport = on; 53 } 54 55 //-------------------------------------------------------------// 56 const ForceFeedback::SupportedEffectList& ForceFeedback::getSupportedEffects() const 40 57 { 41 58 return mSupportedEffects; 42 59 } 60 61 //-------------------------------------------------------------// 62 bool ForceFeedback::supportsEffect(Effect::EForce force, Effect::EType type) const 63 { 64 const std::pair<SupportedEffectList::const_iterator, SupportedEffectList::const_iterator> 65 iterRange = mSupportedEffects.equal_range(force); 66 SupportedEffectList::const_iterator iter; 67 for (iter = iterRange.first; iter != iterRange.second; iter++) 68 { 69 if ((*iter).second == type) 70 return true; 71 } 72 73 return false; 74 } -
code/trunk/src/ois/OISForceFeedback.h
r1505 r5695 36 36 { 37 37 public: 38 ForceFeedback() {}38 ForceFeedback(); 39 39 virtual ~ForceFeedback() {} 40 40 … … 44 44 Individual effects have gain levels; however, this affects all 45 45 effects at once. 46 Note: If the device does not support master gain setting, nothing is done 46 47 @param level 47 48 A value between 0.0 and 1.0 represent the percentage of gain. 1.0 … … 56 57 the joystick back to center. DirectInput only has an on/off setting, 57 58 whereas linux has levels.. Though, we go with DI's on/off mode only 59 Note: If the device does not support auto-centering, nothing is done 58 60 @param auto_on 59 61 true to turn auto centering on, false to turn off. … … 87 89 virtual short getFFAxesNumber() = 0; 88 90 89 typedef std::map<Effect::EForce, Effect::EType> SupportedEffectList; 91 /** 92 @remarks 93 Get the current load (%, in [0, 100] of the FF device memory 94 */ 95 virtual unsigned short getFFMemoryLoad() = 0; 96 97 typedef std::multimap<Effect::EForce, Effect::EType> SupportedEffectList; 90 98 /** 91 99 @remarks … … 94 102 const SupportedEffectList& getSupportedEffects() const; 95 103 104 /** 105 @remarks 106 Tell if a given force / effect type pair is supported 107 */ 108 bool supportsEffect(Effect::EForce force, Effect::EType type) const; 109 96 110 void _addEffectTypes( Effect::EForce force, Effect::EType type ); 111 void _setGainSupport( bool on ); 112 void _setAutoCenterSupport( bool on ); 97 113 98 114 protected: 99 115 SupportedEffectList mSupportedEffects; 116 bool mSetGainSupport; 117 bool mSetAutoCenterSupport; 100 118 }; 101 119 } -
code/trunk/src/ois/OISJoyStick.h
r1505 r5695 32 32 33 33 //! POV / HAT Joystick component 34 class _OISExport Pov : Component34 class _OISExport Pov : public Component 35 35 { 36 36 public: … … 51 51 52 52 //! A sliding axis - only used in Win32 Right Now 53 class _OISExport Slider : Component53 class _OISExport Slider : public Component 54 54 { 55 55 public: -
code/trunk/src/ois/OISPrereqs.h
r1505 r5695 167 167 { 168 168 public: 169 Button() {}170 Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {} ;169 Button() : Component(OIS_Button), pushed(false) {} 170 Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {} 171 171 //! true if pushed, false otherwise 172 172 bool pushed; -
code/trunk/src/ois/changes_orxonox.diff
r2710 r5695 1 --- linux/EventHelpers.cpp (revision 5668) 2 +++ linux/EventHelpers.cpp (working copy) 3 @@ -35,6 +35,20 @@ 4 # include <iostream> 5 #endif 6 7 +// Fixes for missing macros in input.h 8 +#ifndef FF_EFFECT_MIN 9 +#define FF_EFFECT_MIN FF_RUMBLE 10 +#endif 11 +#ifndef FF_EFFECT_MAX 12 +#define FF_EFFECT_MAX FF_RAMP 13 +#endif 14 +#ifndef FF_WAVEFORM_MIN 15 +#define FF_WAVEFORM_MIN FF_SQUARE 16 +#endif 17 +#ifndef FF_WAVEFORM_MAX 18 +#define FF_WAVEFORM_MAX FF_CUSTOM 19 +#endif 20 + 21 using namespace std; 22 using namespace OIS; 23 24 -
code/trunk/src/ois/linux/EventHelpers.cpp
r1505 r5695 34 34 #ifdef OIS_LINUX_JOY_DEBUG 35 35 # include <iostream> 36 using namespace std; 37 #endif 38 36 #endif 37 38 // Fixes for missing macros in input.h 39 #ifndef FF_EFFECT_MIN 40 #define FF_EFFECT_MIN FF_RUMBLE 41 #endif 42 #ifndef FF_EFFECT_MAX 43 #define FF_EFFECT_MAX FF_RAMP 44 #endif 45 #ifndef FF_WAVEFORM_MIN 46 #define FF_WAVEFORM_MIN FF_SQUARE 47 #endif 48 #ifndef FF_WAVEFORM_MAX 49 #define FF_WAVEFORM_MAX FF_CUSTOM 50 #endif 51 52 using namespace std; 39 53 using namespace OIS; 40 54 … … 42 56 { 43 57 public: 44 std::vector<int> buttons, relAxes, absAxes, hats;58 vector<int> buttons, relAxes, absAxes, hats; 45 59 }; 46 60 47 bool inline isBitSet(unsigned long bits[], unsigned int bit) 48 { 49 return (bits[bit/(sizeof(long)*8)] >> ((bit)%(sizeof(long)*8))) & 1; 50 } 61 bool inline isBitSet(unsigned char bits[], unsigned int bit) 62 { 63 return (bits[(bit)/(sizeof(unsigned char)*8)] >> ((bit)%(sizeof(unsigned char)*8))) & 1; 64 } 65 51 66 //-----------------------------------------------------------------------------// 52 67 DeviceComponentInfo getComponentInfo( int deviceID ) 53 68 { 54 unsigned long info[2][((KEY_MAX-1)/(sizeof(long)*8)) +1]; 55 memset( info, 0, sizeof(info) ); 69 unsigned char ev_bits[1 + EV_MAX/8/sizeof(unsigned char)]; 70 memset( ev_bits, 0, sizeof(ev_bits) ); 71 72 //Read "all" (hence 0) components of the device 73 #ifdef OIS_LINUX_JOY_DEBUG 74 cout << "EventUtils::getComponentInfo(" << deviceID 75 << ") : Reading device events features" << endl; 76 #endif 77 if (ioctl(deviceID, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) 78 OIS_EXCEPT( E_General, "Could not read device events features"); 56 79 57 80 DeviceComponentInfo components; 58 59 //Read "all" (hence 0) components of the device - read into first entry60 ioctl(deviceID, EVIOCGBIT(0, EV_MAX), info[0]);61 81 62 82 for (int i = 0; i < EV_MAX; i++) 63 83 { 64 if( isBitSet( info[0], i) )84 if( isBitSet(ev_bits, i) ) 65 85 { 66 memset( info[1], 0, sizeof(info) / 2 ); 67 ioctl(deviceID, EVIOCGBIT(i, KEY_MAX), info[1]); 68 for (int j = 0; j < KEY_MAX; j++) 86 // Absolute axis. 87 if(i == EV_ABS) 69 88 { 70 if( isBitSet(info[1], j) ) 89 unsigned char abs_bits[1 + ABS_MAX/8/sizeof(unsigned char)]; 90 memset( abs_bits, 0, sizeof(abs_bits) ); 91 92 #ifdef OIS_LINUX_JOY_DEBUG 93 cout << "EventUtils::getComponentInfo(" << deviceID 94 << ") : Reading device absolute axis features" << endl; 95 #endif 96 97 if (ioctl(deviceID, EVIOCGBIT(i, sizeof(abs_bits)), abs_bits) == -1) 98 OIS_EXCEPT( E_General, "Could not read device absolute axis features"); 99 100 for (int j = 0; j < ABS_MAX; j++) 71 101 { 72 if(i == EV_ABS)102 if( isBitSet(abs_bits, j) ) 73 103 { 74 104 //input_absinfo abInfo; … … 89 119 } 90 120 } 91 else if(i == EV_REL) 121 } 122 } 123 else if(i == EV_REL) 124 { 125 unsigned char rel_bits[1 + REL_MAX/8/sizeof(unsigned char)]; 126 memset( rel_bits, 0, sizeof(rel_bits) ); 127 128 #ifdef OIS_LINUX_JOY_DEBUG 129 cout << "EventUtils::getComponentInfo(" << deviceID 130 << ") : Reading device relative axis features" << endl; 131 #endif 132 133 if (ioctl(deviceID, EVIOCGBIT(i, sizeof(rel_bits)), rel_bits) == -1) 134 OIS_EXCEPT( E_General, "Could not read device relative axis features"); 135 136 for (int j = 0; j < REL_MAX; j++) 137 { 138 if( isBitSet(rel_bits, j) ) 92 139 { 93 140 components.relAxes.push_back(j); 94 141 } 95 else if(i == EV_KEY) 142 } 143 } 144 else if(i == EV_KEY) 145 { 146 unsigned char key_bits[1 + KEY_MAX/8/sizeof(unsigned char)]; 147 memset( key_bits, 0, sizeof(key_bits) ); 148 149 #ifdef OIS_LINUX_JOY_DEBUG 150 cout << "EventUtils::getComponentInfo(" << deviceID 151 << ") : Reading device buttons features" << endl; 152 #endif 153 154 if (ioctl(deviceID, EVIOCGBIT(i, sizeof(key_bits)), key_bits) == -1) 155 OIS_EXCEPT( E_General, "Could not read device buttons features"); 156 157 for (int j = 0; j < KEY_MAX; j++) 158 { 159 if( isBitSet(key_bits, j) ) 96 160 { 97 161 components.buttons.push_back(j); 98 162 } 99 163 } … … 108 172 bool EventUtils::isJoyStick( int deviceID, JoyStickInfo &js ) 109 173 { 110 if( deviceID == -1 ) OIS_EXCEPT( E_General, "Error with File Descriptor" ); 174 if( deviceID == -1 ) 175 OIS_EXCEPT( E_General, "Error with File Descriptor" ); 111 176 112 177 DeviceComponentInfo info = getComponentInfo( deviceID ); … … 117 182 118 183 #ifdef OIS_LINUX_JOY_DEBUG 119 cout << "\n\nDisplaying ButtonMapping Status:";184 cout << endl << "Displaying ButtonMapping Status:" << endl; 120 185 #endif 121 for( std::vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i )186 for(vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i ) 122 187 { 123 188 //Check to ensure we find at least one joy only button 124 if( (*i >= BTN_JOYSTICK && *i <= BTN_THUMBR) || (*i >= BTN_WHEEL && *i <= BTN_GEAR_UP ) ) 189 if( (*i >= BTN_JOYSTICK && *i < BTN_GAMEPAD) 190 || (*i >= BTN_GAMEPAD && *i < BTN_DIGI) 191 || (*i >= BTN_WHEEL && *i < KEY_OK) ) 125 192 joyButtonFound = true; 126 193 … … 128 195 129 196 #ifdef OIS_LINUX_JOY_DEBUG 130 cout << "\nButton Mapping ID (hex): " << hex << *i << " OIS Button Num: " << dec << (buttons-1); 197 cout << "Button Mapping ID (hex): " << hex << *i 198 << " OIS Button Num: " << dec << buttons-1 << endl; 131 199 #endif 132 200 } 201 #ifdef OIS_LINUX_JOY_DEBUG 202 cout << endl; 203 #endif 133 204 134 205 //Joy Buttons found, so it must be a joystick or pad … … 140 211 js.axes = info.relAxes.size() + info.absAxes.size(); 141 212 js.hats = info.hats.size(); 213 #ifdef OIS_LINUX_JOY_DEBUG 214 cout << endl << "Device name:" << js.vendor << endl; 215 cout << "Device unique Id:" << getUniqueId(deviceID) << endl; 216 cout << "Device physical location:" << getPhysicalLocation(deviceID) << endl; 217 #endif 142 218 143 219 //Map the Axes 144 220 #ifdef OIS_LINUX_JOY_DEBUG 145 cout << "\n\nDisplaying AxisMapping Status:";221 cout << endl << "Displaying AxisMapping Status:" << endl; 146 222 #endif 147 223 int axes = 0; 148 for( std::vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i )224 for(vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i ) 149 225 { 150 226 js.axis_map[*i] = axes; 151 227 228 #ifdef OIS_LINUX_JOY_DEBUG 229 cout << "EventUtils::isJoyStick(" << deviceID 230 << ") : Reading device absolute axis #" << *i << " features" << endl; 231 #endif 232 152 233 input_absinfo absinfo; 153 ioctl(deviceID, EVIOCGABS(*i), &absinfo); 234 if (ioctl(deviceID, EVIOCGABS(*i), &absinfo) == -1) 235 OIS_EXCEPT( E_General, "Could not read device absolute axis features"); 154 236 js.axis_range[axes] = Range(absinfo.minimum, absinfo.maximum); 155 237 156 238 #ifdef OIS_LINUX_JOY_DEBUG 157 cout << "\nAxis Mapping ID (hex): " << hex << *i << " OIS Axis Num: " << dec << axes; 239 cout << "Axis Mapping ID (hex): " << hex << *i 240 << " OIS Axis Num: " << dec << axes << endl; 158 241 #endif 159 242 … … 166 249 167 250 //-----------------------------------------------------------------------------// 168 std::string EventUtils::getName( int deviceID ) 169 { 251 string EventUtils::getName( int deviceID ) 252 { 253 #ifdef OIS_LINUX_JOY_DEBUG 254 cout << "EventUtils::getName(" << deviceID 255 << ") : Reading device name" << endl; 256 #endif 257 170 258 char name[OIS_DEVICE_NAME]; 171 ioctl(deviceID, EVIOCGNAME(OIS_DEVICE_NAME), name); 172 return std::string(name); 259 if (ioctl(deviceID, EVIOCGNAME(OIS_DEVICE_NAME), name) == -1) 260 OIS_EXCEPT( E_General, "Could not read device name"); 261 return string(name); 262 } 263 264 //-----------------------------------------------------------------------------// 265 string EventUtils::getUniqueId( int deviceID ) 266 { 267 #ifdef OIS_LINUX_JOY_DEBUG 268 cout << "EventUtils::getUniqueId(" << deviceID 269 << ") : Reading device unique Id" << endl; 270 #endif 271 272 #define OIS_DEVICE_UNIQUE_ID 128 273 char uId[OIS_DEVICE_UNIQUE_ID]; 274 if (ioctl(deviceID, EVIOCGUNIQ(OIS_DEVICE_UNIQUE_ID), uId) == -1) 275 OIS_EXCEPT( E_General, "Could not read device unique Id"); 276 return string(uId); 277 } 278 279 //-----------------------------------------------------------------------------// 280 string EventUtils::getPhysicalLocation( int deviceID ) 281 { 282 #ifdef OIS_LINUX_JOY_DEBUG 283 cout << "EventUtils::getPhysicalLocation(" << deviceID 284 << ") : Reading device physical location" << endl; 285 #endif 286 287 #define OIS_DEVICE_PHYSICAL_LOCATION 128 288 char physLoc[OIS_DEVICE_PHYSICAL_LOCATION]; 289 if (ioctl(deviceID, EVIOCGPHYS(OIS_DEVICE_PHYSICAL_LOCATION), physLoc) == -1) 290 OIS_EXCEPT( E_General, "Could not read device physical location"); 291 return string(physLoc); 173 292 } 174 293 … … 177 296 { 178 297 //Linux Event to OIS Event Mappings 179 std::map<int, Effect::EType> typeMap;298 map<int, Effect::EType> typeMap; 180 299 typeMap[FF_CONSTANT] = Effect::Constant; 181 300 typeMap[FF_RAMP] = Effect::Ramp; … … 191 310 typeMap[FF_CUSTOM] = Effect::Custom; 192 311 193 std::map<int, Effect::EForce> forceMap;312 map<int, Effect::EForce> forceMap; 194 313 forceMap[FF_CONSTANT] = Effect::ConstantForce; 195 forceMap[FF_RAMP] = Effect::RampForce; 196 forceMap[FF_PERIODIC] = Effect::PeriodicForce; 197 forceMap[FF_CUSTOM] = Effect::CustomForce; 314 forceMap[FF_RAMP] = Effect::RampForce; 315 forceMap[FF_SPRING] = Effect::ConditionalForce; 316 forceMap[FF_FRICTION] = Effect::ConditionalForce; 317 forceMap[FF_SQUARE] = Effect::PeriodicForce; 318 forceMap[FF_TRIANGLE] = Effect::PeriodicForce; 319 forceMap[FF_SINE] = Effect::PeriodicForce; 320 forceMap[FF_SAW_UP] = Effect::PeriodicForce; 321 forceMap[FF_SAW_DOWN] = Effect::PeriodicForce; 322 forceMap[FF_DAMPER] = Effect::ConditionalForce; 323 forceMap[FF_INERTIA] = Effect::ConditionalForce; 324 forceMap[FF_CUSTOM] = Effect::CustomForce; 198 325 199 326 //Remove any previously existing memory and create fresh 200 327 removeForceFeedback( ff ); 201 *ff = new LinuxForceFeedback(); 202 203 unsigned long info[4] = {0,0,0,0}; 204 unsigned long subinfo[4]= {0,0,0,0}; 205 206 //Read overall force feedback components of the device 207 ioctl(deviceID, EVIOCGBIT(EV_FF, sizeof(long)*4), info); 328 *ff = new LinuxForceFeedback(deviceID); 329 330 //Read overall force feedback features 331 unsigned char ff_bits[1 + FF_MAX/8/sizeof(unsigned char)]; 332 memset(ff_bits, 0, sizeof(ff_bits)); 333 334 #ifdef OIS_LINUX_JOY_DEBUG 335 cout << "EventUtils::enumerateForceFeedback(" << deviceID 336 << ") : Reading device force feedback features" << endl; 337 #endif 338 339 if (ioctl(deviceID, EVIOCGBIT(EV_FF, sizeof(ff_bits)), ff_bits) == -1) 340 OIS_EXCEPT( E_General, "Could not read device force feedback features"); 341 342 343 #ifdef OIS_LINUX_JOY_DEBUG 344 cout << "FF bits: " << hex; 345 for (int i = 0; i < sizeof(ff_bits); i++) 346 cout << (int)ff_bits[i]; 347 cout << endl << dec; 348 #endif 208 349 209 350 //FF Axes 210 //if( isBitSet( info, ABS_X) ) //X Axis211 //if( isBitSet( info, ABS_Y) ) //Y Axis212 //if( isBitSet( info, ABS_WHEEL) ) //Wheel351 //if( isBitSet(ff_bits, ABS_X) ) //X Axis 352 //if( isBitSet(ff_bits, ABS_Y) ) //Y Axis 353 //if( isBitSet(ff_bits, ABS_WHEEL) ) //Wheel 213 354 214 355 //FF Effects 215 for( int effect = ABS_WHEEL+1; effect < FF_MAX; effect++ )356 for( int effect = FF_EFFECT_MIN; effect <= FF_WAVEFORM_MAX; effect++ ) 216 357 { 217 if(isBitSet(info, effect)) 358 // The RUMBLE force type is ignored, as periodic force one is more powerfull. 359 // The PERIODIC force type is processed later, for each associated periodic effect type. 360 if (effect == FF_RUMBLE || effect == FF_PERIODIC) 361 continue; 362 363 if(isBitSet(ff_bits, effect)) 218 364 { 219 //std::cout << "\tEffect Type: " << effect << std::endl; 220 memset(subinfo, 0, sizeof(subinfo)); 221 //Read any info about this supported effect 222 ioctl(deviceID, EVIOCGBIT(effect, sizeof(long)*4), subinfo); 223 for( int force = 0; force < FF_MAX; force++ ) 224 { 225 if(isBitSet(subinfo, force)) 226 (*ff)->_addEffectTypes( forceMap[force], typeMap[effect] ); 227 } 365 #ifdef OIS_LINUX_JOY_DEBUG 366 cout << " Effect Type: " << Effect::getEffectTypeName(typeMap[effect]) << endl; 367 #endif 368 369 (*ff)->_addEffectTypes( forceMap[effect], typeMap[effect] ); 228 370 } 229 371 } 372 373 //FF device properties 374 if (isBitSet(ff_bits, FF_GAIN)) 375 (*ff)->_setGainSupport(true); 376 377 if (isBitSet(ff_bits, FF_AUTOCENTER)) 378 (*ff)->_setAutoCenterSupport(true); 230 379 231 380 //Check to see if any effects were added, else destroy the pointer -
code/trunk/src/ois/linux/EventHelpers.h
r1505 r5695 43 43 44 44 static std::string getName( int deviceID ); 45 static std::string getUniqueId( int deviceID ); 46 static std::string getPhysicalLocation( int deviceID ); 45 47 }; 46 48 } -
code/trunk/src/ois/linux/LinuxForceFeedback.cpp
r1505 r5695 24 24 #include "OISException.h" 25 25 26 #include <cstdlib> 27 #include <errno.h> 28 #include <memory.h> 29 26 30 using namespace OIS; 27 31 28 //--------------------------------------------------------------// 29 LinuxForceFeedback::LinuxForceFeedback() 30 { 31 } 32 // 0 = No trace; 1 = Important traces; 2 = Debug traces 33 #define OIS_LINUX_JOYFF_DEBUG 1 34 35 #ifdef OIS_LINUX_JOYFF_DEBUG 36 # include <iostream> 37 using namespace std; 38 #endif 39 40 //--------------------------------------------------------------// 41 LinuxForceFeedback::LinuxForceFeedback(int deviceID) : 42 ForceFeedback(), mJoyStick(deviceID) 43 { 44 } 45 32 46 //--------------------------------------------------------------// 33 47 LinuxForceFeedback::~LinuxForceFeedback() 34 48 { 35 } 36 37 //--------------------------------------------------------------// 38 void LinuxForceFeedback::setMasterGain(float) 39 { 40 } 41 42 //--------------------------------------------------------------// 43 void LinuxForceFeedback::setAutoCenterMode(bool) 44 { 45 } 46 47 //--------------------------------------------------------------// 48 void LinuxForceFeedback::upload( const Effect* /*effect*/ ) 49 { 50 } 51 52 //--------------------------------------------------------------// 53 void LinuxForceFeedback::modify( const Effect* /*effect*/ ) 54 { 55 } 56 57 //--------------------------------------------------------------// 58 void LinuxForceFeedback::remove( const Effect* /*effect*/ ) 59 { 60 } 61 49 // Unload all effects. 50 for(EffectList::iterator i = mEffectList.begin(); i != mEffectList.end(); ++i ) 51 { 52 struct ff_effect *linEffect = i->second; 53 if( linEffect ) 54 _unload(linEffect->id); 55 } 56 57 mEffectList.clear(); 58 } 59 60 //--------------------------------------------------------------// 61 unsigned short LinuxForceFeedback::getFFMemoryLoad() 62 { 63 int nEffects = -1; 64 if (ioctl(mJoyStick, EVIOCGEFFECTS, &nEffects) == -1) 65 OIS_EXCEPT(E_General, "Unknown error reading max number of uploaded effects."); 66 #if (OIS_LINUX_JOYFF_DEBUG > 1) 67 cout << "LinuxForceFeedback("<< mJoyStick 68 << ") : Read device max number of uploaded effects : " << nEffects << endl; 69 #endif 70 71 return (unsigned short int)(nEffects > 0 ? 100.0*mEffectList.size()/nEffects : 100); 72 } 73 74 //--------------------------------------------------------------// 75 void LinuxForceFeedback::setMasterGain(float value) 76 { 77 if (!mSetGainSupport) 78 { 79 #if (OIS_LINUX_JOYFF_DEBUG > 0) 80 cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting master gain " 81 << "is not supported by the device" << endl; 82 #endif 83 return; 84 } 85 86 struct input_event event; 87 88 memset(&event, 0, sizeof(event)); 89 event.type = EV_FF; 90 event.code = FF_GAIN; 91 if (value < 0.0) 92 value = 0.0; 93 else if (value > 1.0) 94 value = 1.0; 95 event.value = (__s32)(value * 0xFFFFUL); 96 97 #if (OIS_LINUX_JOYFF_DEBUG > 0) 98 cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting master gain to " 99 << value << " => " << event.value << endl; 100 #endif 101 102 if (write(mJoyStick, &event, sizeof(event)) != sizeof(event)) { 103 OIS_EXCEPT(E_General, "Unknown error changing master gain."); 104 } 105 } 106 107 //--------------------------------------------------------------// 108 void LinuxForceFeedback::setAutoCenterMode(bool enabled) 109 { 110 if (!mSetAutoCenterSupport) 111 { 112 #if (OIS_LINUX_JOYFF_DEBUG > 0) 113 cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting auto-center mode " 114 << "is not supported by the device" << endl; 115 #endif 116 return; 117 } 118 119 struct input_event event; 120 121 memset(&event, 0, sizeof(event)); 122 event.type = EV_FF; 123 event.code = FF_AUTOCENTER; 124 event.value = (__s32)(enabled*0xFFFFFFFFUL); 125 126 #if (OIS_LINUX_JOYFF_DEBUG > 0) 127 cout << "LinuxForceFeedback("<< mJoyStick << ") : Toggling auto-center to " 128 << enabled << " => 0x" << hex << event.value << dec << endl; 129 #endif 130 131 if (write(mJoyStick, &event, sizeof(event)) != sizeof(event)) { 132 OIS_EXCEPT(E_General, "Unknown error toggling auto-center."); 133 } 134 } 135 136 //--------------------------------------------------------------// 137 void LinuxForceFeedback::upload( const Effect* effect ) 138 { 139 switch( effect->force ) 140 { 141 case OIS::Effect::ConstantForce: 142 _updateConstantEffect(effect); 143 break; 144 case OIS::Effect::ConditionalForce: 145 _updateConditionalEffect(effect); 146 break; 147 case OIS::Effect::PeriodicForce: 148 _updatePeriodicEffect(effect); 149 break; 150 case OIS::Effect::RampForce: 151 _updateRampEffect(effect); 152 break; 153 case OIS::Effect::CustomForce: 154 //_updateCustomEffect(effect); 155 //break; 156 default: 157 OIS_EXCEPT(E_NotImplemented, "Requested force not implemented yet, sorry!"); 158 break; 159 } 160 } 161 162 //--------------------------------------------------------------// 163 void LinuxForceFeedback::modify( const Effect* effect ) 164 { 165 upload(effect); 166 } 167 168 //--------------------------------------------------------------// 169 void LinuxForceFeedback::remove( const Effect* effect ) 170 { 171 //Get the effect - if it exists 172 EffectList::iterator i = mEffectList.find(effect->_handle); 173 if( i != mEffectList.end() ) 174 { 175 struct ff_effect *linEffect = i->second; 176 if( linEffect ) 177 { 178 _stop(effect->_handle); 179 180 _unload(effect->_handle); 181 182 free(linEffect); 183 184 mEffectList.erase(i); 185 } 186 else 187 mEffectList.erase(i); 188 } 189 } 190 191 //--------------------------------------------------------------// 192 // To Signed16/Unsigned15 safe conversions 193 #define MaxUnsigned15Value 0x7FFF 194 #define toUnsigned15(value) \ 195 (__u16)((value) < 0 ? 0 : ((value) > MaxUnsigned15Value ? MaxUnsigned15Value : (value))) 196 197 #define MaxSigned16Value 0x7FFF 198 #define MinSigned16Value -0x7FFF 199 #define toSigned16(value) \ 200 (__s16)((value) < MinSigned16Value ? MinSigned16Value : ((value) > MaxSigned16Value ? MaxSigned16Value : (value))) 201 202 // OIS to Linux duration 203 #define LinuxInfiniteDuration 0xFFFF 204 #define OISDurationUnitMS 1000 // OIS duration unit (microseconds), expressed in milliseconds (theLinux duration unit) 205 206 // linux/input.h : All duration values are expressed in ms. Values above 32767 ms (0x7fff) 207 // should not be used and have unspecified results. 208 #define LinuxDuration(oisDuration) ((oisDuration) == Effect::OIS_INFINITE ? LinuxInfiniteDuration \ 209 : toUnsigned15((oisDuration)/OISDurationUnitMS)) 210 211 212 // OIS to Linux levels 213 #define OISMaxLevel 10000 214 #define LinuxMaxLevel 0x7FFF 215 216 // linux/input.h : Valid range for the attack and fade levels is 0x0000 - 0x7fff 217 #define LinuxPositiveLevel(oisLevel) toUnsigned15(LinuxMaxLevel*(long)(oisLevel)/OISMaxLevel) 218 219 #define LinuxSignedLevel(oisLevel) toSigned16(LinuxMaxLevel*(long)(oisLevel)/OISMaxLevel) 220 221 222 //--------------------------------------------------------------// 223 void LinuxForceFeedback::_setCommonProperties(struct ff_effect *event, 224 struct ff_envelope *ffenvelope, 225 const Effect* effect, const Envelope *envelope ) 226 { 227 memset(event, 0, sizeof(struct ff_effect)); 228 229 if (envelope && ffenvelope && envelope->isUsed()) { 230 ffenvelope->attack_length = LinuxDuration(envelope->attackLength); 231 ffenvelope->attack_level = LinuxPositiveLevel(envelope->attackLevel); 232 ffenvelope->fade_length = LinuxDuration(envelope->fadeLength); 233 ffenvelope->fade_level = LinuxPositiveLevel(envelope->fadeLevel); 234 } 235 236 #if (OIS_LINUX_JOYFF_DEBUG > 1) 237 cout << endl; 238 if (envelope && ffenvelope) 239 { 240 cout << " Enveloppe :" << endl 241 << " AttackLen : " << envelope->attackLength 242 << " => " << ffenvelope->attack_length << endl 243 << " AttackLvl : " << envelope->attackLevel 244 << " => " << ffenvelope->attack_level << endl 245 << " FadeLen : " << envelope->fadeLength 246 << " => " << ffenvelope->fade_length << endl 247 << " FadeLvl : " << envelope->fadeLevel 248 << " => " << ffenvelope->fade_level << endl; 249 } 250 #endif 251 252 event->direction = (__u16)(1 + (effect->direction*45.0+135.0)*0xFFFFUL/360.0); 253 254 #if (OIS_LINUX_JOYFF_DEBUG > 1) 255 cout << " Direction : " << Effect::getDirectionName(effect->direction) 256 << " => 0x" << hex << event->direction << dec << endl; 257 #endif 258 259 // TODO trigger_button 0 vs. -1 260 event->trigger.button = effect->trigger_button; // < 0 ? 0 : effect->trigger_button; 261 event->trigger.interval = LinuxDuration(effect->trigger_interval); 262 263 #if (OIS_LINUX_JOYFF_DEBUG > 1) 264 cout << " Trigger :" << endl 265 << " Button : " << effect->trigger_button 266 << " => " << event->trigger.button << endl 267 << " Interval : " << effect->trigger_interval 268 << " => " << event->trigger.interval << endl; 269 #endif 270 271 event->replay.length = LinuxDuration(effect->replay_length); 272 event->replay.delay = LinuxDuration(effect->replay_delay); 273 274 #if (OIS_LINUX_JOYFF_DEBUG > 1) 275 cout << " Replay :" << endl 276 << " Length : " << effect->replay_length 277 << " => " << event->replay.length << endl 278 << " Delay : " << effect->replay_delay 279 << " => " << event->replay.delay << endl; 280 #endif 281 } 282 283 //--------------------------------------------------------------// 284 void LinuxForceFeedback::_updateConstantEffect( const Effect* eff ) 285 { 286 struct ff_effect event; 287 288 ConstantEffect *effect = static_cast<ConstantEffect*>(eff->getForceEffect()); 289 290 _setCommonProperties(&event, &event.u.constant.envelope, eff, &effect->envelope); 291 292 event.type = FF_CONSTANT; 293 event.id = -1; 294 295 event.u.constant.level = LinuxSignedLevel(effect->level); 296 297 #if (OIS_LINUX_JOYFF_DEBUG > 1) 298 cout << " Level : " << effect->level 299 << " => " << event.u.constant.level << endl; 300 #endif 301 302 _upload(&event, eff); 303 } 304 305 //--------------------------------------------------------------// 306 void LinuxForceFeedback::_updateRampEffect( const Effect* eff ) 307 { 308 struct ff_effect event; 309 310 RampEffect *effect = static_cast<RampEffect*>(eff->getForceEffect()); 311 312 _setCommonProperties(&event, &event.u.constant.envelope, eff, &effect->envelope); 313 314 event.type = FF_RAMP; 315 event.id = -1; 316 317 event.u.ramp.start_level = LinuxSignedLevel(effect->startLevel); 318 event.u.ramp.end_level = LinuxSignedLevel(effect->endLevel); 319 320 #if (OIS_LINUX_JOYFF_DEBUG > 1) 321 cout << " StartLevel : " << effect->startLevel 322 << " => " << event.u.ramp.start_level << endl 323 << " EndLevel : " << effect->endLevel 324 << " => " << event.u.ramp.end_level << endl; 325 #endif 326 327 _upload(&event, eff); 328 } 329 330 //--------------------------------------------------------------// 331 void LinuxForceFeedback::_updatePeriodicEffect( const Effect* eff ) 332 { 333 struct ff_effect event; 334 335 PeriodicEffect *effect = static_cast<PeriodicEffect*>(eff->getForceEffect()); 336 337 _setCommonProperties(&event, &event.u.periodic.envelope, eff, &effect->envelope); 338 339 event.type = FF_PERIODIC; 340 event.id = -1; 341 342 switch( eff->type ) 343 { 344 case OIS::Effect::Square: 345 event.u.periodic.waveform = FF_SQUARE; 346 break; 347 case OIS::Effect::Triangle: 348 event.u.periodic.waveform = FF_TRIANGLE; 349 break; 350 case OIS::Effect::Sine: 351 event.u.periodic.waveform = FF_SINE; 352 break; 353 case OIS::Effect::SawToothUp: 354 event.u.periodic.waveform = FF_SAW_UP; 355 break; 356 case OIS::Effect::SawToothDown: 357 event.u.periodic.waveform = FF_SAW_DOWN; 358 break; 359 // Note: No support for Custom periodic force effect for the moment 360 //case OIS::Effect::Custom: 361 //event.u.periodic.waveform = FF_CUSTOM; 362 //break; 363 default: 364 OIS_EXCEPT(E_General, "No such available effect for Periodic force!"); 365 break; 366 } 367 368 event.u.periodic.period = LinuxDuration(effect->period); 369 event.u.periodic.magnitude = LinuxPositiveLevel(effect->magnitude); 370 event.u.periodic.offset = LinuxPositiveLevel(effect->offset); 371 event.u.periodic.phase = (__u16)(effect->phase*event.u.periodic.period/36000.0); // ????? 372 373 // Note: No support for Custom periodic force effect for the moment 374 event.u.periodic.custom_len = 0; 375 event.u.periodic.custom_data = 0; 376 377 #if (OIS_LINUX_JOYFF_DEBUG > 1) 378 cout << " Magnitude : " << effect->magnitude 379 << " => " << event.u.periodic.magnitude << endl 380 << " Period : " << effect->period 381 << " => " << event.u.periodic.period << endl 382 << " Offset : " << effect->offset 383 << " => " << event.u.periodic.offset << endl 384 << " Phase : " << effect->phase 385 << " => " << event.u.periodic.phase << endl; 386 #endif 387 388 _upload(&event, eff); 389 } 390 391 //--------------------------------------------------------------// 392 void LinuxForceFeedback::_updateConditionalEffect( const Effect* eff ) 393 { 394 struct ff_effect event; 395 396 ConditionalEffect *effect = static_cast<ConditionalEffect*>(eff->getForceEffect()); 397 398 _setCommonProperties(&event, NULL, eff, NULL); 399 400 switch( eff->type ) 401 { 402 case OIS::Effect::Friction: 403 event.type = FF_FRICTION; 404 break; 405 case OIS::Effect::Damper: 406 event.type = FF_DAMPER; 407 break; 408 case OIS::Effect::Inertia: 409 event.type = FF_INERTIA; 410 break; 411 case OIS::Effect::Spring: 412 event.type = FF_SPRING; 413 break; 414 default: 415 OIS_EXCEPT(E_General, "No such available effect for Conditional force!"); 416 break; 417 } 418 419 event.id = -1; 420 421 event.u.condition[0].right_saturation = LinuxSignedLevel(effect->rightSaturation); 422 event.u.condition[0].left_saturation = LinuxSignedLevel(effect->leftSaturation); 423 event.u.condition[0].right_coeff = LinuxSignedLevel(effect->rightCoeff); 424 event.u.condition[0].left_coeff = LinuxSignedLevel(effect->leftCoeff); 425 event.u.condition[0].deadband = LinuxPositiveLevel(effect->deadband);// Unit ?? 426 event.u.condition[0].center = LinuxSignedLevel(effect->center); // Unit ?? TODO ? 427 428 // TODO support for second condition 429 event.u.condition[1] = event.u.condition[0]; 430 431 #if (OIS_LINUX_JOYFF_DEBUG > 1) 432 cout << " Condition[0] : " << endl 433 << " RightSaturation : " << effect->rightSaturation 434 << " => " << event.u.condition[0].right_saturation << endl 435 << " LeftSaturation : " << effect->leftSaturation 436 << " => " << event.u.condition[0]. left_saturation << endl 437 << " RightCoefficient : " << effect->rightCoeff 438 << " => " << event.u.condition[0].right_coeff << endl 439 << " LeftCoefficient : " << effect->leftCoeff 440 << " => " << event.u.condition[0].left_coeff << endl 441 << " DeadBand : " << effect->deadband 442 << " => " << event.u.condition[0].deadband << endl 443 << " Center : " << effect->center 444 << " => " << event.u.condition[0].center << endl; 445 cout << " Condition[1] : Not implemented" << endl; 446 #endif 447 _upload(&event, eff); 448 } 449 450 //--------------------------------------------------------------// 451 void LinuxForceFeedback::_upload( struct ff_effect* ffeffect, const Effect* effect) 452 { 453 struct ff_effect *linEffect = 0; 454 455 //Get the effect - if it exists 456 EffectList::iterator i = mEffectList.find(effect->_handle); 457 //It has been created already 458 if( i != mEffectList.end() ) 459 linEffect = i->second; 460 461 if( linEffect == 0 ) 462 { 463 #if (OIS_LINUX_JOYFF_DEBUG > 1) 464 cout << endl << "LinuxForceFeedback("<< mJoyStick << ") : Adding new effect : " 465 << Effect::getEffectTypeName(effect->type) << endl; 466 #endif 467 468 //This effect has not yet been created, so create it in the device 469 if (ioctl(mJoyStick, EVIOCSFF, ffeffect) == -1) { 470 // TODO device full check 471 // OIS_EXCEPT(E_DeviceFull, "Remove an effect before adding more!"); 472 OIS_EXCEPT(E_General, "Unknown error creating effect (may be the device is full)->.."); 473 } 474 475 // Save returned effect handle 476 effect->_handle = ffeffect->id; 477 478 // Save a copy of the uploaded effect for later simple modifications 479 linEffect = (struct ff_effect *)calloc(1, sizeof(struct ff_effect)); 480 memcpy(linEffect, ffeffect, sizeof(struct ff_effect)); 481 482 mEffectList[effect->_handle] = linEffect; 483 484 // Start playing the effect. 485 _start(effect->_handle); 486 } 487 else 488 { 489 #if (OIS_LINUX_JOYFF_DEBUG > 1) 490 cout << endl << "LinuxForceFeedback("<< mJoyStick << ") : Replacing effect : " 491 << Effect::getEffectTypeName(effect->type) << endl; 492 #endif 493 494 // Keep same id/handle, as this is just an update in the device. 495 ffeffect->id = effect->_handle; 496 497 // Update effect in the device. 498 if (ioctl(mJoyStick, EVIOCSFF, ffeffect) == -1) { 499 OIS_EXCEPT(E_General, "Unknown error updating an effect->.."); 500 } 501 502 // Update local linEffect for next time. 503 memcpy(linEffect, ffeffect, sizeof(struct ff_effect)); 504 } 505 506 #if (OIS_LINUX_JOYFF_DEBUG > 1) 507 cout << "LinuxForceFeedback("<< mJoyStick 508 << ") : Effect handle : " << effect->_handle << endl; 509 #endif 510 } 511 512 //--------------------------------------------------------------// 513 void LinuxForceFeedback::_stop( int handle) { 514 struct input_event stop; 515 516 stop.type = EV_FF; 517 stop.code = handle; 518 stop.value = 0; 519 520 #if (OIS_LINUX_JOYFF_DEBUG > 1) 521 cout << endl << "LinuxForceFeedback("<< mJoyStick 522 << ") : Stopping effect with handle " << handle << endl; 523 #endif 524 525 if (write(mJoyStick, &stop, sizeof(stop)) != sizeof(stop)) { 526 OIS_EXCEPT(E_General, "Unknown error stopping effect->.."); 527 } 528 } 529 530 //--------------------------------------------------------------// 531 void LinuxForceFeedback::_start( int handle) { 532 struct input_event play; 533 534 play.type = EV_FF; 535 play.code = handle; 536 play.value = 1; // Play once. 537 538 #if (OIS_LINUX_JOYFF_DEBUG > 1) 539 cout << endl << "LinuxForceFeedback("<< mJoyStick 540 << ") : Starting effect with handle " << handle << endl; 541 #endif 542 543 if (write(mJoyStick, &play, sizeof(play)) != sizeof(play)) { 544 OIS_EXCEPT(E_General, "Unknown error playing effect->.."); 545 } 546 } 547 548 //--------------------------------------------------------------// 549 void LinuxForceFeedback::_unload( int handle) 550 { 551 #if (OIS_LINUX_JOYFF_DEBUG > 1) 552 cout << endl << "LinuxForceFeedback("<< mJoyStick 553 << ") : Removing effect with handle " << handle << endl; 554 #endif 555 556 if (ioctl(mJoyStick, EVIOCRMFF, handle) == -1) { 557 OIS_EXCEPT(E_General, "Unknown error removing effect->.."); 558 } 559 } -
code/trunk/src/ois/linux/LinuxForceFeedback.h
r1505 r5695 26 26 #include "linux/LinuxPrereqs.h" 27 27 #include "OISForceFeedback.h" 28 #include <linux/input.h> 28 29 29 30 namespace OIS … … 32 33 { 33 34 public: 34 LinuxForceFeedback( );35 LinuxForceFeedback(int deviceID); 35 36 ~LinuxForceFeedback(); 36 37 … … 50 51 void remove( const Effect* effect ); 51 52 52 /** FF is not yet implemented fully on Linux.. just retun 0 for now. todo, xxx */ 53 short int getFFAxesNumber() { return 0; } 53 /** FF is not yet implemented fully on Linux.. just return -1 for now. todo, xxx */ 54 short int getFFAxesNumber() { return -1; } 55 56 /** @copydoc ForceFeedback::getFFMemoryLoad */ 57 unsigned short getFFMemoryLoad(); 58 59 protected: 60 61 //Sets the common properties to all effects 62 void _setCommonProperties(struct ff_effect *event, struct ff_envelope *ffenvelope, 63 const Effect* effect, const Envelope *envelope ); 64 65 //Specific Effect Settings 66 void _updateConstantEffect( const Effect* effect ); 67 void _updateRampEffect( const Effect* effect ); 68 void _updatePeriodicEffect( const Effect* effect ); 69 void _updateConditionalEffect( const Effect* effect ); 70 //void _updateCustomEffect( const Effect* effect ); 71 72 void _upload( struct ff_effect* ffeffect, const Effect* effect); 73 void _stop( int handle); 74 void _start( int handle); 75 void _unload( int handle); 76 77 // Map of currently uploaded effects (handle => effect) 78 typedef std::map<int, struct ff_effect *> EffectList; 79 EffectList mEffectList; 80 81 // Joystick device (file) descriptor. 82 int mJoyStick; 54 83 }; 55 84 } -
code/trunk/src/ois/linux/LinuxJoyStickEvents.cpp
r1505 r5695 37 37 38 38 #include <sstream> 39 # include <iostream> 40 using namespace std; 39 41 40 42 using namespace OIS; 41 43 42 44 //#define OIS_LINUX_JOY_DEBUG 43 44 #ifdef OIS_LINUX_JOY_DEBUG45 # include <iostream>46 using namespace std;47 #endif48 45 49 46 //-------------------------------------------------------------------// … … 114 111 115 112 #ifdef OIS_LINUX_JOY_DEBUG 116 std::cout << "\nButton Code: " << js[i].code << ", OIS Value: " << button << std::endl;113 cout << "\nButton Code: " << js[i].code << ", OIS Value: " << button << endl; 117 114 #endif 118 115 … … 132 129 break; 133 130 } 134 case EV_ABS: //Absoulte Axis 131 132 case EV_ABS: //Absolute Axis 135 133 { 136 134 //A Stick (BrakeDefine is the highest possible Axis) … … 138 136 { 139 137 int axis = mAxisMap[js[i].code]; 140 assert( axis < 32 && "Too many axes , not supported. Report this to OIS forums!" );141 138 assert( axis < 32 && "Too many axes (Max supported is 32). Report this to OIS forums!" ); 139 142 140 axisMoved[axis] = true; 143 141 … … 190 188 break; 191 189 } 192 //Relative Axes (Do any joysticks actually have a relative axis?) 193 case EV_REL: 190 191 192 case EV_REL: //Relative Axes (Do any joystick actually have a relative axis?) 193 #ifdef OIS_LINUX_JOY_DEBUG 194 cout << "\nWarning: Relatives axes not supported yet" << endl; 195 #endif 196 break; 194 197 default: break; 195 198 } … … 243 246 for(int i = 0; i < 64; ++i ) 244 247 { 245 st d::stringstream s;248 stringstream s; 246 249 s << "/dev/input/event" << i; 247 int fd = open( s.str().c_str(), O_RD ONLY|O_NONBLOCK );250 int fd = open( s.str().c_str(), O_RDWR |O_NONBLOCK ); 248 251 if(fd == -1) 249 252 continue; 250 253 251 254 #ifdef OIS_LINUX_JOY_DEBUG 252 std::cout << "\nOpening " << s.str() << "...";255 cout << "Opening " << s.str() << "..." << endl; 253 256 #endif 254 257 try … … 259 262 joys.push_back(js); 260 263 #ifdef OIS_LINUX_JOY_DEBUG 261 std::cout << "\n__Joystick added to list";264 cout << "=> Joystick added to list." << endl; 262 265 #endif 263 266 } … … 265 268 { 266 269 #ifdef OIS_LINUX_JOY_DEBUG 267 std::cout << "\n__Not a joystick!!";270 cout << "=> Not a joystick." << endl; 268 271 #endif 269 272 close(fd); … … 273 276 { 274 277 #ifdef OIS_LINUX_JOY_DEBUG 275 std::cout << "\nException caught!!";278 cout << "Exception caught!!" << endl; 276 279 #endif 277 280 close(fd); -
code/trunk/src/ois/win32/Win32ForceFeedback.cpp
r1505 r5695 25 25 #include <Math.h> 26 26 27 #if defined (_DEBUG) 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> 28 32 #include <sstream> 33 using namespace std; 29 34 #endif 30 35 … … 32 37 33 38 //--------------------------------------------------------------// 34 Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* joy) : 35 mHandles(0), mJoyStick(joy) 36 { 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 37 47 } 38 48 … … 45 55 LPDIRECTINPUTEFFECT dxEffect = i->second; 46 56 if( dxEffect ) 57 { 47 58 dxEffect->Unload(); 59 dxEffect->Release(); 60 } 48 61 } 49 62 50 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; 51 92 } 52 93 … … 86 127 //have been unlaoded 87 128 if( SUCCEEDED(dxEffect->Unload()) ) 129 { 130 dxEffect->Release(); 88 131 mEffectList.erase(i); 132 } 89 133 } 90 134 else … … 111 155 DIPropGain.dwData = gain_level; 112 156 113 mJoyStick->SetProperty(DIPROP_FFGAIN, &DIPropGain.diph); 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 114 168 } 115 169 … … 117 171 void Win32ForceFeedback::setAutoCenterMode( bool auto_on ) 118 172 { 119 //DI Property DIPROPAUTOCENTER_OFF = 0, 1 is on120 173 DIPROPDWORD DIPropAutoCenter; 121 174 DIPropAutoCenter.diph.dwSize = sizeof(DIPropAutoCenter); … … 123 176 DIPropAutoCenter.diph.dwObj = 0; 124 177 DIPropAutoCenter.diph.dwHow = DIPH_DEVICE; 125 DIPropAutoCenter.dwData = auto_on; 126 127 //hr = 128 mJoyStick->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph); 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 129 191 } 130 192 … … 132 194 void Win32ForceFeedback::_updateConstantEffect( const Effect* effect ) 133 195 { 196 ConstantEffect *eff = static_cast<ConstantEffect*>(effect->getForceEffect()); 197 134 198 DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 135 199 LONG rglDirection[2] = { 0, 0 }; 200 DIENVELOPE diEnvelope; 136 201 DICONSTANTFORCE cf; 137 202 DIEFFECT diEffect; … … 139 204 //Currently only support 1 axis 140 205 //if( effect->getNumAxes() == 1 ) 141 cf.lMagnitude = static_cast<ConstantEffect*>(effect->getForceEffect())->level; 142 143 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICONSTANTFORCE), &cf, effect); 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); 144 214 _upload(GUID_ConstantForce, &diEffect, effect); 145 215 } … … 148 218 void Win32ForceFeedback::_updateRampEffect( const Effect* effect ) 149 219 { 220 RampEffect *eff = static_cast<RampEffect*>(effect->getForceEffect()); 221 150 222 DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 151 223 LONG rglDirection[2] = { 0, 0 }; 224 DIENVELOPE diEnvelope; 152 225 DIRAMPFORCE rf; 153 226 DIEFFECT diEffect; 154 227 155 228 //Currently only support 1 axis 156 rf.lStart = static_cast<RampEffect*>(effect->getForceEffect())->startLevel;157 rf.lEnd = static_cast<RampEffect*>(effect->getForceEffect())->endLevel;158 159 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DIRAMPFORCE), &rf, effect);229 rf.lStart = eff->startLevel; 230 rf.lEnd = eff->endLevel; 231 232 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIRAMPFORCE), &rf, effect, &eff->envelope ); 160 233 _upload(GUID_RampForce, &diEffect, effect); 161 234 } … … 164 237 void Win32ForceFeedback::_updatePeriodicEffect( const Effect* effect ) 165 238 { 239 PeriodicEffect *eff = static_cast<PeriodicEffect*>(effect->getForceEffect()); 240 166 241 DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 167 242 LONG rglDirection[2] = { 0, 0 }; 243 DIENVELOPE diEnvelope; 168 244 DIPERIODIC pf; 169 245 DIEFFECT diEffect; 170 246 171 247 //Currently only support 1 axis 172 pf.dwMagnitude = static_cast<PeriodicEffect*>(effect->getForceEffect())->magnitude;173 pf.lOffset = static_cast<PeriodicEffect*>(effect->getForceEffect())->offset;174 pf.dwPhase = static_cast<PeriodicEffect*>(effect->getForceEffect())->phase;175 pf.dwPeriod = static_cast<PeriodicEffect*>(effect->getForceEffect())->period;176 177 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DIPERIODIC), &pf, effect);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 ); 178 254 179 255 switch( effect->type ) … … 191 267 void Win32ForceFeedback::_updateConditionalEffect( const Effect* effect ) 192 268 { 269 ConditionalEffect *eff = static_cast<ConditionalEffect*>(effect->getForceEffect()); 270 193 271 DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 194 272 LONG rglDirection[2] = { 0, 0 }; 273 DIENVELOPE diEnvelope; 195 274 DICONDITION cf; 196 275 DIEFFECT diEffect; 197 276 198 cf.lOffset = static_cast<ConditionalEffect*>(effect->getForceEffect())->deadband;199 cf.lPositiveCoefficient = static_cast<ConditionalEffect*>(effect->getForceEffect())->rightCoeff;200 cf.lNegativeCoefficient = static_cast<ConditionalEffect*>(effect->getForceEffect())->leftCoeff;201 cf.dwPositiveSaturation = static_cast<ConditionalEffect*>(effect->getForceEffect())->rightSaturation;202 cf.dwNegativeSaturation = static_cast<ConditionalEffect*>(effect->getForceEffect())->leftSaturation;203 cf.lDeadBand = static_cast<ConditionalEffect*>(effect->getForceEffect())->deadband;204 205 _setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICONDITION), &cf, effect);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 ); 206 285 207 286 switch( effect->type ) … … 218 297 void Win32ForceFeedback::_updateCustomEffect( const Effect* /*effect*/ ) 219 298 { 299 //CustomEffect *eff = static_cast<CustomEffect*>(effect->getForceEffect()); 300 // 220 301 //DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y }; 221 302 //LONG rglDirection[2] = { 0, 0 }; 303 //DIENVELOPE diEnvelope; 222 304 //DICUSTOMFORCE cf; 223 305 //DIEFFECT diEffect; … … 226 308 //cf.cSamples = 0; 227 309 //cf.rglForceData = 0; 228 //_setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICUSTOMFORCE), &cf, effect);310 //_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICUSTOMFORCE), &cf, effect, &eff->envelope); 229 311 //_upload(GUID_CustomForce, &diEffect, effect); 230 312 } … … 233 315 void Win32ForceFeedback::_setCommonProperties( 234 316 DIEFFECT* diEffect, DWORD* rgdwAxes, 235 LONG* rglDirection, D WORD struct_size,236 LPVOID struct_type, const Effect* effect )317 LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size, 318 LPVOID struct_type, const Effect* effect, const Envelope* envelope ) 237 319 { 238 320 ZeroMemory(diEffect, sizeof(DIEFFECT)); … … 240 322 diEffect->dwSize = sizeof(DIEFFECT); 241 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; 242 378 diEffect->dwDuration = effect->replay_length; 243 diEffect->dwSamplePeriod = 0; 244 diEffect->dwGain = DI_FFNOMINALMAX; 245 diEffect->dwTriggerButton = DIEB_NOTRIGGER; 246 diEffect->dwTriggerRepeatInterval = 0; 247 diEffect->cAxes = effect->getNumAxes(); 248 diEffect->rgdwAxes = rgdwAxes; 249 diEffect->rglDirection = rglDirection; 250 diEffect->lpEnvelope = 0; 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 251 389 diEffect->cbTypeSpecificParams = struct_size; 252 390 diEffect->lpvTypeSpecificParams = struct_type; 253 diEffect->dwStartDelay = effect->replay_delay;254 391 } 255 392 … … 295 432 void Win32ForceFeedback::_addEffectSupport( LPCDIEFFECTINFO pdei ) 296 433 { 297 //Determine what the effect is and how it corresponds to our OIS's Enums 298 //We could save the GUIDs too, however, we will just use the predefined 299 //ones later 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 300 502 if( pdei->guid == GUID_ConstantForce ) 301 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Constant );503 _addEffectTypes(eForce, Effect::Constant ); 302 504 else if( pdei->guid == GUID_Triangle ) 303 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Triangle );505 _addEffectTypes(eForce, Effect::Triangle ); 304 506 else if( pdei->guid == GUID_Spring ) 305 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Spring );507 _addEffectTypes(eForce, Effect::Spring ); 306 508 else if( pdei->guid == GUID_Friction ) 307 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Friction );509 _addEffectTypes(eForce, Effect::Friction ); 308 510 else if( pdei->guid == GUID_Square ) 309 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Square );511 _addEffectTypes(eForce, Effect::Square ); 310 512 else if( pdei->guid == GUID_Sine ) 311 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Sine );513 _addEffectTypes(eForce, Effect::Sine ); 312 514 else if( pdei->guid == GUID_SawtoothUp ) 313 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothUp );515 _addEffectTypes(eForce, Effect::SawToothUp ); 314 516 else if( pdei->guid == GUID_SawtoothDown ) 315 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothDown );517 _addEffectTypes(eForce, Effect::SawToothDown ); 316 518 else if( pdei->guid == GUID_Damper ) 317 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Damper );519 _addEffectTypes(eForce, Effect::Damper ); 318 520 else if( pdei->guid == GUID_Inertia ) 319 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Inertia );521 _addEffectTypes(eForce, Effect::Inertia ); 320 522 else if( pdei->guid == GUID_CustomForce ) 321 _addEffectTypes( (Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Custom );523 _addEffectTypes(eForce, Effect::Custom ); 322 524 else if( pdei->guid == GUID_RampForce ) 323 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Ramp ); 525 _addEffectTypes(eForce, Effect::Ramp ); 526 324 527 #if defined (_DEBUG) 325 528 //Only care about this for Debugging Purposes … … 333 536 #endif 334 537 } 538 539 //--------------------------------------------------------------// 540 void Win32ForceFeedback::_addFFAxis() 541 { 542 mFFAxes++; 543 } -
code/trunk/src/ois/win32/Win32ForceFeedback.h
r1505 r5695 34 34 Win32ForceFeedback() {} 35 35 public: 36 Win32ForceFeedback(IDirectInputDevice8* joy);36 Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps); 37 37 ~Win32ForceFeedback(); 38 38 … … 52 52 void setAutoCenterMode( bool auto_on ); 53 53 54 /** @copydoc ForceFeedback::getFFAxesNumber 55 xxx todo - Actually return correct number 56 */ 57 short getFFAxesNumber() {return 1;} 54 /** @copydoc ForceFeedback::getFFAxesNumber */ 55 short getFFAxesNumber(); 56 57 /** @copydoc ForceFeedback::getFFMemoryLoad */ 58 unsigned short getFFMemoryLoad(); 58 59 59 60 /** … … 64 65 void _addEffectSupport( LPCDIEFFECTINFO pdei ); 65 66 67 /** 68 @remarks 69 Internal use.. Used during axis enumeration to get number of FF axes 70 support effects. 71 */ 72 void _addFFAxis(); 73 66 74 protected: 75 67 76 //Specific Effect Settings 68 77 void _updateConstantEffect( const Effect* effect ); … … 71 80 void _updateConditionalEffect( const Effect* effect ); 72 81 void _updateCustomEffect( const Effect* effect ); 82 73 83 //Sets the common properties to all effects 74 84 void _setCommonProperties( DIEFFECT* diEffect, DWORD* rgdwAxes, 75 LONG* rglDirection, D WORD struct_size,76 LPVOID struct_type, const Effect* effect );85 LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size, 86 LPVOID struct_type, const Effect* effect, const Envelope* envelope ); 77 87 //Actually do the upload 78 88 void _upload( GUID, DIEFFECT*, const Effect* ); 79 89 90 // Map of currently uploaded effects (handle => effect) 80 91 typedef std::map<int,LPDIRECTINPUTEFFECT> EffectList; 81 92 EffectList mEffectList; 82 //Simple unique handle creation - allows for upto 2+ million effects 93 94 //Simple unique handle creation - allows for upto 2+ billion effects 83 95 //during the lifetime of application. Hopefully, that is enough. 84 96 int mHandles; 85 97 98 // Joystick device descriptor. 86 99 IDirectInputDevice8* mJoyStick; 100 101 // Joystick capabilities. 102 const DIDEVCAPS* mpDIJoyCaps; 103 104 // Number of axis supporting FF. 105 short mFFAxes; 87 106 }; 88 107 } -
code/trunk/src/ois/win32/Win32InputManager.cpp
r1505 r5695 75 75 hInst = GetModuleHandle(0); 76 76 77 //Create the device77 //Create the input system 78 78 hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL ); 79 79 if (FAILED(hr)) … … 82 82 //Ok, now we have DirectInput, parse whatever extra settings were sent to us 83 83 _parseConfigSettings( paramList ); 84 85 // Enumerate devices ... 84 86 _enumerateDevices(); 85 87 } … … 116 118 { 117 119 //Enumerate all attached devices 118 mDirectInput->EnumDevices(NULL , _DIEnumKbdCallback, this, DIEDFL_ATTACHEDONLY);119 } 120 121 //--------------------------------------------------------------------------------// 122 BOOL CALLBACK Win32InputManager::_DIEnum KbdCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)120 mDirectInput->EnumDevices(NULL , _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY); 121 } 122 123 //--------------------------------------------------------------------------------// 124 BOOL CALLBACK Win32InputManager::_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef) 123 125 { 124 126 Win32InputManager *_this_ = static_cast<Win32InputManager*>(pvRef); 127 128 // Register only game devices (keyboard and mouse are managed differently). 125 129 if( GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK || 126 130 GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD || -
code/trunk/src/ois/win32/Win32InputManager.h
r1505 r5695 81 81 82 82 //! Used during device enumeration 83 static BOOL CALLBACK _DIEnum KbdCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);83 static BOOL CALLBACK _DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef); 84 84 85 85 //! Keep a list of all joysticks enumerated, but not in use -
code/trunk/src/ois/win32/Win32JoyStick.cpp
r1505 r5695 82 82 mState.mAxes.clear(); 83 83 84 delete ff_device; 85 ff_device = 0; 86 84 if (ff_device) 85 { 86 delete ff_device; 87 ff_device = 0; 88 } 89 90 // Create direct input joystick device. 91 if(FAILED(mDirectInput->CreateDevice(deviceGuid, &mJoyStick, NULL))) 92 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!"); 93 94 // Set DIJoystick2 data format. 95 if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2))) 96 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!"); 97 98 // Set cooperative level as specified when creating input manager. 99 HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle(); 100 if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting))) 101 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!"); 102 103 // Set buffer size. 87 104 DIPROPDWORD dipdw; 88 89 105 dipdw.diph.dwSize = sizeof(DIPROPDWORD); 90 106 dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); … … 93 109 dipdw.dwData = JOYSTICK_DX_BUFFERSIZE; 94 110 95 if(FAILED(mDirectInput->CreateDevice(deviceGuid, &mJoyStick, NULL)))96 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> Could not initialize joy device!");97 98 if(FAILED(mJoyStick->SetDataFormat(&c_dfDIJoystick2)))99 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> data format error!");100 101 HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();102 103 if(FAILED(mJoyStick->SetCooperativeLevel( hwin, coopSetting)))104 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize() >> failed to set cooperation level!");105 106 111 if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) ) 107 OIS_EXCEPT( E_General, "Win32 Mouse::Win32Mouse >> Failed to set buffer size property" );108 109 // Enumerate all axes/buttons/sliders/etc before aquiring112 OIS_EXCEPT( E_General, "Win32JoyStick::_initialize >> Failed to set buffer size property" ); 113 114 // Enumerate all axes/buttons/sliders/force feedback/etc before aquiring 110 115 _enumerate(); 111 116 … … 118 123 void Win32JoyStick::_enumerate() 119 124 { 120 //We can check force feedback here too 121 DIDEVCAPS DIJoyCaps; 122 DIJoyCaps.dwSize = sizeof(DIDEVCAPS); 123 mJoyStick->GetCapabilities(&DIJoyCaps); 124 125 mPOVs = (short)DIJoyCaps.dwPOVs; 126 127 mState.mButtons.resize(DIJoyCaps.dwButtons); 128 mState.mAxes.resize(DIJoyCaps.dwAxes); 125 // Get joystick capabilities. 126 mDIJoyCaps.dwSize = sizeof(DIDEVCAPS); 127 if( FAILED(mJoyStick->GetCapabilities(&mDIJoyCaps)) ) 128 OIS_EXCEPT( E_General, "Win32JoyStick::_enumerate >> Failed to get capabilities" ); 129 130 // => Number of POVs 131 mPOVs = (short)mDIJoyCaps.dwPOVs; 132 133 // => Number of buttons and axes. 134 mState.mButtons.resize(mDIJoyCaps.dwButtons); 135 mState.mAxes.resize(mDIJoyCaps.dwAxes); 136 137 // Enumerate all Force Feedback effects (if any) 138 mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL); 129 139 130 140 //Reset the axis mapping enumeration value 131 141 _AxisNumber = 0; 132 142 133 //Enumerate Force Feedback (if any) 134 mJoyStick->EnumEffects(DIEnumEffectsCallback, this, DIEFT_ALL); 135 136 //Enumerate and set axis constraints (and check FF Axes) 143 // Enumerate and set axis constraints (and check FF Axes) 137 144 mJoyStick->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS); 138 145 } … … 181 188 OIS_EXCEPT( E_General, "Win32JoyStick::_DIEnumDeviceObjectsCallback >> Failed to set min/max range property" ); 182 189 183 //Check if FF Axes 190 //Check if FF Axes, and if so, increment counter 184 191 if((lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 ) 185 192 { 186 193 if( _this->ff_device ) 187 194 { 188 //todo - increment force feedback axis count195 _this->ff_device->_addFFAxis(); 189 196 } 190 197 } 191 198 199 //Force the flags for gain and auto-center support to true, 200 //as DInput has no API to query the device for these capabilities 201 //(the only way to know is to try them ...) 202 if( _this->ff_device ) 203 { 204 _this->ff_device->_setGainSupport(true); 205 _this->ff_device->_setAutoCenterSupport(true); 206 } 207 192 208 return DIENUM_CONTINUE; 193 209 } … … 198 214 Win32JoyStick* _this = (Win32JoyStick*)pvRef; 199 215 200 //Create the FF classafter we know there is at least one effect type216 //Create the FF instance only after we know there is at least one effect type 201 217 if( _this->ff_device == 0 ) 202 _this->ff_device = new Win32ForceFeedback(_this->mJoyStick);218 _this->ff_device = new Win32ForceFeedback(_this->mJoyStick, &_this->mDIJoyCaps); 203 219 204 220 _this->ff_device->_addEffectSupport( pdei ); -
code/trunk/src/ois/win32/Win32JoyStick.h
r1505 r5695 60 60 IDirectInput8* mDirectInput; 61 61 IDirectInputDevice8* mJoyStick; 62 DIDEVCAPS mDIJoyCaps; 63 62 64 DWORD coopSetting; 63 65 GUID deviceGuid; -
code/trunk/src/ois/win32/Win32KeyBoard.cpp
r1505 r5695 238 238 return 0; 239 239 240 unsigned char buff[3] = {0,0,0}; 241 int ascii = ToAsciiEx(vk, kc, keyState, (LPWORD) buff, 0, layout); 242 //WCHAR wide[3]; 243 //int ascii = ToUnicodeEx(vk, kc, keyState, wide, 3, 0, layout); 240 WCHAR buff[3] = {0}; 241 int ascii = ToUnicodeEx(vk, kc, keyState, buff, 3, 0, layout); 242 244 243 if(ascii == 1 && deadKey != '\0' ) 245 244 {
Note: See TracChangeset
for help on using the changeset viewer.