Changeset 5668 for code/branches/resource2/src/ois/linux
- Timestamp:
- Aug 22, 2009, 11:16:34 PM (15 years ago)
- Location:
- code/branches/resource2/src/ois/linux
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/resource2/src/ois/linux/EventHelpers.cpp
r1505 r5668 34 34 #ifdef OIS_LINUX_JOY_DEBUG 35 35 # include <iostream> 36 using namespace std; 37 #endif 38 36 #endif 37 38 using namespace std; 39 39 using namespace OIS; 40 40 … … 42 42 { 43 43 public: 44 std::vector<int> buttons, relAxes, absAxes, hats;44 vector<int> buttons, relAxes, absAxes, hats; 45 45 }; 46 46 47 bool inline isBitSet(unsigned long bits[], unsigned int bit) 48 { 49 return (bits[bit/(sizeof(long)*8)] >> ((bit)%(sizeof(long)*8))) & 1; 50 } 47 bool inline isBitSet(unsigned char bits[], unsigned int bit) 48 { 49 return (bits[(bit)/(sizeof(unsigned char)*8)] >> ((bit)%(sizeof(unsigned char)*8))) & 1; 50 } 51 51 52 //-----------------------------------------------------------------------------// 52 53 DeviceComponentInfo getComponentInfo( int deviceID ) 53 54 { 54 unsigned long info[2][((KEY_MAX-1)/(sizeof(long)*8)) +1]; 55 memset( info, 0, sizeof(info) ); 55 unsigned char ev_bits[1 + EV_MAX/8/sizeof(unsigned char)]; 56 memset( ev_bits, 0, sizeof(ev_bits) ); 57 58 //Read "all" (hence 0) components of the device 59 #ifdef OIS_LINUX_JOY_DEBUG 60 cout << "EventUtils::getComponentInfo(" << deviceID 61 << ") : Reading device events features" << endl; 62 #endif 63 if (ioctl(deviceID, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1) 64 OIS_EXCEPT( E_General, "Could not read device events features"); 56 65 57 66 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 67 62 68 for (int i = 0; i < EV_MAX; i++) 63 69 { 64 if( isBitSet( info[0], i) )70 if( isBitSet(ev_bits, i) ) 65 71 { 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++) 72 // Absolute axis. 73 if(i == EV_ABS) 69 74 { 70 if( isBitSet(info[1], j) ) 75 unsigned char abs_bits[1 + ABS_MAX/8/sizeof(unsigned char)]; 76 memset( abs_bits, 0, sizeof(abs_bits) ); 77 78 #ifdef OIS_LINUX_JOY_DEBUG 79 cout << "EventUtils::getComponentInfo(" << deviceID 80 << ") : Reading device absolute axis features" << endl; 81 #endif 82 83 if (ioctl(deviceID, EVIOCGBIT(i, sizeof(abs_bits)), abs_bits) == -1) 84 OIS_EXCEPT( E_General, "Could not read device absolute axis features"); 85 86 for (int j = 0; j < ABS_MAX; j++) 71 87 { 72 if(i == EV_ABS)88 if( isBitSet(abs_bits, j) ) 73 89 { 74 90 //input_absinfo abInfo; … … 89 105 } 90 106 } 91 else if(i == EV_REL) 107 } 108 } 109 else if(i == EV_REL) 110 { 111 unsigned char rel_bits[1 + REL_MAX/8/sizeof(unsigned char)]; 112 memset( rel_bits, 0, sizeof(rel_bits) ); 113 114 #ifdef OIS_LINUX_JOY_DEBUG 115 cout << "EventUtils::getComponentInfo(" << deviceID 116 << ") : Reading device relative axis features" << endl; 117 #endif 118 119 if (ioctl(deviceID, EVIOCGBIT(i, sizeof(rel_bits)), rel_bits) == -1) 120 OIS_EXCEPT( E_General, "Could not read device relative axis features"); 121 122 for (int j = 0; j < REL_MAX; j++) 123 { 124 if( isBitSet(rel_bits, j) ) 92 125 { 93 126 components.relAxes.push_back(j); 94 127 } 95 else if(i == EV_KEY) 128 } 129 } 130 else if(i == EV_KEY) 131 { 132 unsigned char key_bits[1 + KEY_MAX/8/sizeof(unsigned char)]; 133 memset( key_bits, 0, sizeof(key_bits) ); 134 135 #ifdef OIS_LINUX_JOY_DEBUG 136 cout << "EventUtils::getComponentInfo(" << deviceID 137 << ") : Reading device buttons features" << endl; 138 #endif 139 140 if (ioctl(deviceID, EVIOCGBIT(i, sizeof(key_bits)), key_bits) == -1) 141 OIS_EXCEPT( E_General, "Could not read device buttons features"); 142 143 for (int j = 0; j < KEY_MAX; j++) 144 { 145 if( isBitSet(key_bits, j) ) 96 146 { 97 147 components.buttons.push_back(j); 98 148 } 99 149 } … … 108 158 bool EventUtils::isJoyStick( int deviceID, JoyStickInfo &js ) 109 159 { 110 if( deviceID == -1 ) OIS_EXCEPT( E_General, "Error with File Descriptor" ); 160 if( deviceID == -1 ) 161 OIS_EXCEPT( E_General, "Error with File Descriptor" ); 111 162 112 163 DeviceComponentInfo info = getComponentInfo( deviceID ); … … 117 168 118 169 #ifdef OIS_LINUX_JOY_DEBUG 119 cout << "\n\nDisplaying ButtonMapping Status:";170 cout << endl << "Displaying ButtonMapping Status:" << endl; 120 171 #endif 121 for( std::vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i )172 for(vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i ) 122 173 { 123 174 //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 ) ) 175 if( (*i >= BTN_JOYSTICK && *i < BTN_GAMEPAD) 176 || (*i >= BTN_GAMEPAD && *i < BTN_DIGI) 177 || (*i >= BTN_WHEEL && *i < KEY_OK) ) 125 178 joyButtonFound = true; 126 179 … … 128 181 129 182 #ifdef OIS_LINUX_JOY_DEBUG 130 cout << "\nButton Mapping ID (hex): " << hex << *i << " OIS Button Num: " << dec << (buttons-1); 183 cout << "Button Mapping ID (hex): " << hex << *i 184 << " OIS Button Num: " << dec << buttons-1 << endl; 131 185 #endif 132 186 } 187 #ifdef OIS_LINUX_JOY_DEBUG 188 cout << endl; 189 #endif 133 190 134 191 //Joy Buttons found, so it must be a joystick or pad … … 140 197 js.axes = info.relAxes.size() + info.absAxes.size(); 141 198 js.hats = info.hats.size(); 199 #ifdef OIS_LINUX_JOY_DEBUG 200 cout << endl << "Device name:" << js.vendor << endl; 201 cout << "Device unique Id:" << getUniqueId(deviceID) << endl; 202 cout << "Device physical location:" << getPhysicalLocation(deviceID) << endl; 203 #endif 142 204 143 205 //Map the Axes 144 206 #ifdef OIS_LINUX_JOY_DEBUG 145 cout << "\n\nDisplaying AxisMapping Status:";207 cout << endl << "Displaying AxisMapping Status:" << endl; 146 208 #endif 147 209 int axes = 0; 148 for( std::vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i )210 for(vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i ) 149 211 { 150 212 js.axis_map[*i] = axes; 151 213 214 #ifdef OIS_LINUX_JOY_DEBUG 215 cout << "EventUtils::isJoyStick(" << deviceID 216 << ") : Reading device absolute axis #" << *i << " features" << endl; 217 #endif 218 152 219 input_absinfo absinfo; 153 ioctl(deviceID, EVIOCGABS(*i), &absinfo); 220 if (ioctl(deviceID, EVIOCGABS(*i), &absinfo) == -1) 221 OIS_EXCEPT( E_General, "Could not read device absolute axis features"); 154 222 js.axis_range[axes] = Range(absinfo.minimum, absinfo.maximum); 155 223 156 224 #ifdef OIS_LINUX_JOY_DEBUG 157 cout << "\nAxis Mapping ID (hex): " << hex << *i << " OIS Axis Num: " << dec << axes; 225 cout << "Axis Mapping ID (hex): " << hex << *i 226 << " OIS Axis Num: " << dec << axes << endl; 158 227 #endif 159 228 … … 166 235 167 236 //-----------------------------------------------------------------------------// 168 std::string EventUtils::getName( int deviceID ) 169 { 237 string EventUtils::getName( int deviceID ) 238 { 239 #ifdef OIS_LINUX_JOY_DEBUG 240 cout << "EventUtils::getName(" << deviceID 241 << ") : Reading device name" << endl; 242 #endif 243 170 244 char name[OIS_DEVICE_NAME]; 171 ioctl(deviceID, EVIOCGNAME(OIS_DEVICE_NAME), name); 172 return std::string(name); 245 if (ioctl(deviceID, EVIOCGNAME(OIS_DEVICE_NAME), name) == -1) 246 OIS_EXCEPT( E_General, "Could not read device name"); 247 return string(name); 248 } 249 250 //-----------------------------------------------------------------------------// 251 string EventUtils::getUniqueId( int deviceID ) 252 { 253 #ifdef OIS_LINUX_JOY_DEBUG 254 cout << "EventUtils::getUniqueId(" << deviceID 255 << ") : Reading device unique Id" << endl; 256 #endif 257 258 #define OIS_DEVICE_UNIQUE_ID 128 259 char uId[OIS_DEVICE_UNIQUE_ID]; 260 if (ioctl(deviceID, EVIOCGUNIQ(OIS_DEVICE_UNIQUE_ID), uId) == -1) 261 OIS_EXCEPT( E_General, "Could not read device unique Id"); 262 return string(uId); 263 } 264 265 //-----------------------------------------------------------------------------// 266 string EventUtils::getPhysicalLocation( int deviceID ) 267 { 268 #ifdef OIS_LINUX_JOY_DEBUG 269 cout << "EventUtils::getPhysicalLocation(" << deviceID 270 << ") : Reading device physical location" << endl; 271 #endif 272 273 #define OIS_DEVICE_PHYSICAL_LOCATION 128 274 char physLoc[OIS_DEVICE_PHYSICAL_LOCATION]; 275 if (ioctl(deviceID, EVIOCGPHYS(OIS_DEVICE_PHYSICAL_LOCATION), physLoc) == -1) 276 OIS_EXCEPT( E_General, "Could not read device physical location"); 277 return string(physLoc); 173 278 } 174 279 … … 177 282 { 178 283 //Linux Event to OIS Event Mappings 179 std::map<int, Effect::EType> typeMap;284 map<int, Effect::EType> typeMap; 180 285 typeMap[FF_CONSTANT] = Effect::Constant; 181 286 typeMap[FF_RAMP] = Effect::Ramp; … … 191 296 typeMap[FF_CUSTOM] = Effect::Custom; 192 297 193 std::map<int, Effect::EForce> forceMap;298 map<int, Effect::EForce> forceMap; 194 299 forceMap[FF_CONSTANT] = Effect::ConstantForce; 195 forceMap[FF_RAMP] = Effect::RampForce; 196 forceMap[FF_PERIODIC] = Effect::PeriodicForce; 197 forceMap[FF_CUSTOM] = Effect::CustomForce; 300 forceMap[FF_RAMP] = Effect::RampForce; 301 forceMap[FF_SPRING] = Effect::ConditionalForce; 302 forceMap[FF_FRICTION] = Effect::ConditionalForce; 303 forceMap[FF_SQUARE] = Effect::PeriodicForce; 304 forceMap[FF_TRIANGLE] = Effect::PeriodicForce; 305 forceMap[FF_SINE] = Effect::PeriodicForce; 306 forceMap[FF_SAW_UP] = Effect::PeriodicForce; 307 forceMap[FF_SAW_DOWN] = Effect::PeriodicForce; 308 forceMap[FF_DAMPER] = Effect::ConditionalForce; 309 forceMap[FF_INERTIA] = Effect::ConditionalForce; 310 forceMap[FF_CUSTOM] = Effect::CustomForce; 198 311 199 312 //Remove any previously existing memory and create fresh 200 313 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); 314 *ff = new LinuxForceFeedback(deviceID); 315 316 //Read overall force feedback features 317 unsigned char ff_bits[1 + FF_MAX/8/sizeof(unsigned char)]; 318 memset(ff_bits, 0, sizeof(ff_bits)); 319 320 #ifdef OIS_LINUX_JOY_DEBUG 321 cout << "EventUtils::enumerateForceFeedback(" << deviceID 322 << ") : Reading device force feedback features" << endl; 323 #endif 324 325 if (ioctl(deviceID, EVIOCGBIT(EV_FF, sizeof(ff_bits)), ff_bits) == -1) 326 OIS_EXCEPT( E_General, "Could not read device force feedback features"); 327 328 329 #ifdef OIS_LINUX_JOY_DEBUG 330 cout << "FF bits: " << hex; 331 for (int i = 0; i < sizeof(ff_bits); i++) 332 cout << (int)ff_bits[i]; 333 cout << endl << dec; 334 #endif 208 335 209 336 //FF Axes 210 //if( isBitSet( info, ABS_X) ) //X Axis211 //if( isBitSet( info, ABS_Y) ) //Y Axis212 //if( isBitSet( info, ABS_WHEEL) ) //Wheel337 //if( isBitSet(ff_bits, ABS_X) ) //X Axis 338 //if( isBitSet(ff_bits, ABS_Y) ) //Y Axis 339 //if( isBitSet(ff_bits, ABS_WHEEL) ) //Wheel 213 340 214 341 //FF Effects 215 for( int effect = ABS_WHEEL+1; effect < FF_MAX; effect++ )342 for( int effect = FF_EFFECT_MIN; effect <= FF_WAVEFORM_MAX; effect++ ) 216 343 { 217 if(isBitSet(info, effect)) 344 // The RUMBLE force type is ignored, as periodic force one is more powerfull. 345 // The PERIODIC force type is processed later, for each associated periodic effect type. 346 if (effect == FF_RUMBLE || effect == FF_PERIODIC) 347 continue; 348 349 if(isBitSet(ff_bits, effect)) 218 350 { 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 } 351 #ifdef OIS_LINUX_JOY_DEBUG 352 cout << " Effect Type: " << Effect::getEffectTypeName(typeMap[effect]) << endl; 353 #endif 354 355 (*ff)->_addEffectTypes( forceMap[effect], typeMap[effect] ); 228 356 } 229 357 } 358 359 //FF device properties 360 if (isBitSet(ff_bits, FF_GAIN)) 361 (*ff)->_setGainSupport(true); 362 363 if (isBitSet(ff_bits, FF_AUTOCENTER)) 364 (*ff)->_setAutoCenterSupport(true); 230 365 231 366 //Check to see if any effects were added, else destroy the pointer -
code/branches/resource2/src/ois/linux/EventHelpers.h
r1505 r5668 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/branches/resource2/src/ois/linux/LinuxForceFeedback.cpp
r1505 r5668 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/branches/resource2/src/ois/linux/LinuxForceFeedback.h
r1505 r5668 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/branches/resource2/src/ois/linux/LinuxJoyStickEvents.cpp
r1505 r5668 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);
Note: See TracChangeset
for help on using the changeset viewer.