Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 5668


Ignore:
Timestamp:
Aug 22, 2009, 11:16:34 PM (15 years ago)
Author:
rgrieder
Message:

Updated OIS library (still 1.2, but CVS version).
There have been some little fixes and support for force feedback on Linux (but this doesn't concern us for now…)

Location:
code/branches/resource2/src/ois
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • code/branches/resource2/src/ois/OISEffect.cpp

    r1505 r5668  
    2929//Perhaps a case of a crazy extreme optimizer :/ (moved to header)
    3030//const unsigned int Effect::OIS_INFINITE = 0xFFFFFFFF;
     31
     32//------------------------------------------------------------------------------//
     33static const char* pszEForceString[] =
     34  { "UnknownForce",
     35    "ConstantForce",
     36    "RampForce",
     37    "PeriodicForce",
     38    "ConditionalForce",
     39    "CustomForce" };
     40
     41const char* Effect::getForceTypeName(Effect::EForce eValue)
     42{
     43  return (eValue >= 0 && eValue < _ForcesNumber) ? pszEForceString[eValue] : "<Bad force type>";
     44}
     45
     46static const char* pszETypeString[] =
     47  { "Unknown",
     48    "Constant",
     49    "Ramp",
     50    "Square", "Triangle", "Sine", "SawToothUp", "SawToothDown",
     51    "Friction", "Damper", "Inertia", "Spring",
     52    "Custom" };
     53
     54const char* Effect::getEffectTypeName(Effect::EType eValue)
     55{
     56  return (eValue >= 0 && eValue < _TypesNumber) ? pszETypeString[eValue] : "<Bad effect type>";
     57}
     58
     59static const char* pszEDirectionString[] =
     60  { "NorthWest", "North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West"};
     61
     62const char* Effect::getDirectionName(Effect::EDirection eValue)
     63{
     64  return (eValue >= 0 && eValue < _DirectionsNumber) ? pszEDirectionString[eValue] : "<Bad direction>";
     65}
    3166
    3267//------------------------------------------------------------------------------//
  • code/branches/resource2/src/ois/OISEffect.h

    r1505 r5668  
    6060                        PeriodicForce,
    6161                        ConditionalForce,
    62                         CustomForce
     62                        CustomForce,
     63                        _ForcesNumber // Always keep in last position.
    6364                };
     65
     66                static const char* getForceTypeName(EForce eValue);
    6467
    6568                //! Type of effect
     
    7982                        Inertia,     //ConditionalForce
    8083                        Spring,      //ConditionalForce
    81                         Custom       //CustomForce
     84                        Custom,      //CustomForce
     85                        _TypesNumber // Always keep in last position.
    8286                };
     87
     88                static const char* getEffectTypeName(EType eValue);
    8389
    8490                //! Direction of the Force
     
    9298                        South,
    9399                        SouthWest,
    94                         West
     100                        West,
     101                        _DirectionsNumber // Always keep in last position.
    95102                };
     103
     104                static const char* getDirectionName(EDirection eValue);
    96105
    97106                /**
     
    168177                An optional envelope to be applied to the start/end of an effect. If any of
    169178                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.
    171180        */
    172181        class _OISExport Envelope : public ForceEffect
     
    178187  #pragma warning (disable : 4800)
    179188#endif
    180                 bool isUsed() { return attackLength | attackLevel | fadeLength | fadeLevel; }
     189                bool isUsed() const { return attackLength | attackLevel | fadeLength | fadeLevel; }
    181190#if defined(OIS_MSVC_COMPILER)
    182191  #pragma warning (pop)
    183192#endif
    184193
    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)
    186199                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)
    188206                unsigned short fadeLevel;
    189207        };
     
    211229                RampEffect() : startLevel(0), endLevel(0) {}
    212230
    213         class Envelope envelope; //Optional envolope
     231        class Envelope envelope; //Optional envelope
    214232                signed short startLevel;  //-10K to +10k
    215233                signed short endLevel;    //-10K to +10k
  • code/branches/resource2/src/ois/OISForceFeedback.cpp

    r1505 r5668  
    2727
    2828//-------------------------------------------------------------//
    29 void ForceFeedback::_addEffectTypes( Effect::EForce force, Effect::EType type )
     29ForceFeedback::ForceFeedback() : mSetGainSupport(false), mSetAutoCenterSupport(false)
    3030{
    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;
    3531}
    3632
    3733//-------------------------------------------------------------//
    38 const ForceFeedback::SupportedEffectList&
    39                                                 ForceFeedback::getSupportedEffects() const
     34void 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//-------------------------------------------------------------//
     44void ForceFeedback::_setGainSupport( bool on )
     45{
     46        mSetGainSupport = on;
     47}
     48
     49//-------------------------------------------------------------//
     50void ForceFeedback::_setAutoCenterSupport( bool on )
     51{
     52        mSetAutoCenterSupport = on;
     53}
     54
     55//-------------------------------------------------------------//
     56const ForceFeedback::SupportedEffectList& ForceFeedback::getSupportedEffects() const
    4057{
    4158        return mSupportedEffects;
    4259}
     60
     61//-------------------------------------------------------------//
     62bool 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/branches/resource2/src/ois/OISForceFeedback.h

    r1505 r5668  
    3636        {
    3737        public:
    38                 ForceFeedback() {}
     38                ForceFeedback();
    3939                virtual ~ForceFeedback() {}
    4040
     
    4444                        Individual effects have gain levels; however, this affects all
    4545                        effects at once.
     46                        Note: If the device does not support master gain setting, nothing is done
    4647                @param level
    4748                        A value between 0.0 and 1.0 represent the percentage of gain. 1.0
     
    5657                        the joystick back to center. DirectInput only has an on/off setting,
    5758                        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
    5860                @param auto_on
    5961                        true to turn auto centering on, false to turn off.
     
    8789        virtual short getFFAxesNumber() = 0;
    8890
    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;
    9098                /**
    9199                @remarks
     
    94102                const SupportedEffectList& getSupportedEffects() const;
    95103
     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
    96110                void _addEffectTypes( Effect::EForce force, Effect::EType type );
     111                void _setGainSupport( bool on );
     112                void _setAutoCenterSupport( bool on );
    97113
    98114        protected:
    99115                SupportedEffectList mSupportedEffects;
     116                bool mSetGainSupport;
     117                bool mSetAutoCenterSupport;
    100118        };
    101119}
  • code/branches/resource2/src/ois/OISJoyStick.h

    r1505 r5668  
    3232
    3333        //! POV / HAT Joystick component
    34         class _OISExport Pov : Component
     34        class _OISExport Pov : public Component
    3535        {
    3636        public:
     
    5151
    5252        //! A sliding axis - only used in Win32 Right Now
    53         class _OISExport Slider : Component
     53        class _OISExport Slider : public Component
    5454        {
    5555        public:
  • code/branches/resource2/src/ois/OISPrereqs.h

    r1505 r5668  
    167167        {
    168168        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) {}
    171171                //! true if pushed, false otherwise
    172172                bool pushed;
  • code/branches/resource2/src/ois/linux/EventHelpers.cpp

    r1505 r5668  
    3434#ifdef OIS_LINUX_JOY_DEBUG
    3535# include <iostream>
    36   using namespace std;
    37 #endif
    38 
     36#endif
     37
     38using namespace std;
    3939using namespace OIS;
    4040
     
    4242{
    4343public:
    44         std::vector<int> buttons, relAxes, absAxes, hats;
     44        vector<int> buttons, relAxes, absAxes, hats;
    4545};
    4646
    47 bool inline isBitSet(unsigned long bits[], unsigned int bit)
    48 {
    49         return (bits[bit/(sizeof(long)*8)] >> ((bit)%(sizeof(long)*8))) & 1;
    50 }
     47bool 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
    5152//-----------------------------------------------------------------------------//
    5253DeviceComponentInfo getComponentInfo( int deviceID )
    5354{
    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");
    5665
    5766        DeviceComponentInfo components;
    58 
    59         //Read "all" (hence 0) components of the device - read into first entry
    60         ioctl(deviceID, EVIOCGBIT(0, EV_MAX), info[0]);
    6167
    6268        for (int i = 0; i < EV_MAX; i++)
    6369        {
    64                 if( isBitSet(info[0], i) )
     70                if( isBitSet(ev_bits, i) )
    6571                {
    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)
    6974                        {
    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++)
    7187                                {
    72                                         if(i == EV_ABS)
     88                                    if( isBitSet(abs_bits, j) )
    7389                                        {
    7490                                                //input_absinfo abInfo;
     
    89105                                                }
    90106                                        }
    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) )
    92125                                        {
    93                                                 components.relAxes.push_back(j);
     126                                            components.relAxes.push_back(j);
    94127                                        }
    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) )
    96146                                        {
    97                                                 components.buttons.push_back(j);
     147                                            components.buttons.push_back(j);
    98148                                        }
    99149                                }
     
    108158bool EventUtils::isJoyStick( int deviceID, JoyStickInfo &js )
    109159{
    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" );
    111162
    112163        DeviceComponentInfo info = getComponentInfo( deviceID );
     
    117168
    118169        #ifdef OIS_LINUX_JOY_DEBUG
    119           cout << "\n\nDisplaying ButtonMapping Status:";
     170        cout << endl << "Displaying ButtonMapping Status:" << endl;
    120171        #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 )
    122173        {
    123174                //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) )
    125178                        joyButtonFound = true;
    126179
     
    128181
    129182                #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;
    131185                #endif
    132186        }
     187        #ifdef OIS_LINUX_JOY_DEBUG
     188        cout << endl;
     189        #endif
    133190
    134191        //Joy Buttons found, so it must be a joystick or pad
     
    140197                js.axes = info.relAxes.size() + info.absAxes.size();
    141198                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
    142204
    143205                //Map the Axes
    144206                #ifdef OIS_LINUX_JOY_DEBUG
    145                   cout << "\n\nDisplaying AxisMapping Status:";
     207                  cout << endl << "Displaying AxisMapping Status:" << endl;
    146208                #endif
    147209                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 )
    149211                {
    150212                        js.axis_map[*i] = axes;
    151213
     214#ifdef OIS_LINUX_JOY_DEBUG
     215                        cout << "EventUtils::isJoyStick(" << deviceID
     216                                          << ") : Reading device absolute axis #" << *i << " features" << endl;
     217#endif
     218
    152219                        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");
    154222                        js.axis_range[axes] = Range(absinfo.minimum, absinfo.maximum);
    155223
    156224                        #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;
    158227                        #endif
    159228
     
    166235
    167236//-----------------------------------------------------------------------------//
    168 std::string EventUtils::getName( int deviceID )
    169 {
     237string EventUtils::getName( int deviceID )
     238{
     239#ifdef OIS_LINUX_JOY_DEBUG
     240        cout << "EventUtils::getName(" << deviceID
     241                 << ") : Reading device name" << endl;
     242#endif
     243
    170244        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//-----------------------------------------------------------------------------//
     251string 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//-----------------------------------------------------------------------------//
     266string 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);
    173278}
    174279
     
    177282{
    178283        //Linux Event to OIS Event Mappings
    179         std::map<int, Effect::EType> typeMap;
     284        map<int, Effect::EType> typeMap;
    180285        typeMap[FF_CONSTANT] = Effect::Constant;
    181286        typeMap[FF_RAMP]     = Effect::Ramp;
     
    191296        typeMap[FF_CUSTOM]   = Effect::Custom;
    192297
    193         std::map<int, Effect::EForce> forceMap;
     298        map<int, Effect::EForce> forceMap;
    194299        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;
    198311
    199312        //Remove any previously existing memory and create fresh
    200313        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
    208335
    209336        //FF Axes
    210         //if( isBitSet(info, ABS_X) ) //X Axis
    211         //if( isBitSet(info, ABS_Y) ) //Y Axis
    212         //if( isBitSet(info, ABS_WHEEL) ) //Wheel
     337        //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
    213340
    214341        //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++ )
    216343        {
    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))
    218350                {
    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] );
    228356                }
    229357        }
     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);
    230365
    231366        //Check to see if any effects were added, else destroy the pointer
  • code/branches/resource2/src/ois/linux/EventHelpers.h

    r1505 r5668  
    4343
    4444                static std::string getName( int deviceID );
     45                static std::string getUniqueId( int deviceID );
     46                static std::string getPhysicalLocation( int deviceID );
    4547        };
    4648}
  • code/branches/resource2/src/ois/linux/LinuxForceFeedback.cpp

    r1505 r5668  
    2424#include "OISException.h"
    2525
     26#include <cstdlib>
     27#include <errno.h>
     28#include <memory.h>
     29
    2630using namespace OIS;
    2731
    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//--------------------------------------------------------------//
     41LinuxForceFeedback::LinuxForceFeedback(int deviceID) :
     42        ForceFeedback(), mJoyStick(deviceID)
     43{
     44}
     45
    3246//--------------------------------------------------------------//
    3347LinuxForceFeedback::~LinuxForceFeedback()
    3448{
    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//--------------------------------------------------------------//
     61unsigned 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//--------------------------------------------------------------//
     75void 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//--------------------------------------------------------------//
     108void 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//--------------------------------------------------------------//
     137void 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//--------------------------------------------------------------//
     163void LinuxForceFeedback::modify( const Effect* effect )
     164{
     165        upload(effect);
     166}
     167
     168//--------------------------------------------------------------//
     169void 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//--------------------------------------------------------------//
     223void 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//--------------------------------------------------------------//
     284void 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//--------------------------------------------------------------//
     306void 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//--------------------------------------------------------------//
     331void 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//--------------------------------------------------------------//
     392void 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//--------------------------------------------------------------//
     451void 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//--------------------------------------------------------------//
     513void 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//--------------------------------------------------------------//
     531void 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//--------------------------------------------------------------//
     549void 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  
    2626#include "linux/LinuxPrereqs.h"
    2727#include "OISForceFeedback.h"
     28#include <linux/input.h>
    2829
    2930namespace OIS
     
    3233        {
    3334        public:
    34                 LinuxForceFeedback();
     35                LinuxForceFeedback(int deviceID);
    3536                ~LinuxForceFeedback();
    3637
     
    5051                void remove( const Effect* effect );
    5152
    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;
    5483        };
    5584}
  • code/branches/resource2/src/ois/linux/LinuxJoyStickEvents.cpp

    r1505 r5668  
    3737
    3838#include <sstream>
     39# include <iostream>
     40using namespace std;
    3941
    4042using namespace OIS;
    4143
    4244//#define OIS_LINUX_JOY_DEBUG
    43 
    44 #ifdef OIS_LINUX_JOY_DEBUG
    45 # include <iostream>
    46   using namespace std;
    47 #endif
    4845
    4946//-------------------------------------------------------------------//
     
    114111
    115112                        #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;
    117114                        #endif
    118115
     
    132129                        break;
    133130                }
    134                 case EV_ABS:  //Absoulte Axis
     131
     132                case EV_ABS:  //Absolute Axis
    135133                {
    136134                        //A Stick (BrakeDefine is the highest possible Axis)
     
    138136                        {
    139137                                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
    142140                                axisMoved[axis] = true;
    143141
     
    190188                        break;
    191189                }
    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;
    194197                default: break;
    195198                }
     
    243246        for(int i = 0; i < 64; ++i )
    244247        {
    245                 std::stringstream s;
     248                stringstream s;
    246249                s << "/dev/input/event" << i;
    247                 int fd = open( s.str().c_str(), O_RDONLY |O_NONBLOCK );
     250                int fd = open( s.str().c_str(), O_RDWR |O_NONBLOCK );
    248251                if(fd == -1)
    249252                        continue;
    250                
     253
    251254        #ifdef OIS_LINUX_JOY_DEBUG
    252           std::cout << "\nOpening " << s.str() << "...";
     255                  cout << "Opening " << s.str() << "..." << endl;
    253256        #endif
    254257                try
     
    259262                                joys.push_back(js);
    260263                #ifdef OIS_LINUX_JOY_DEBUG
    261                   std::cout << "\n__Joystick added to list";
     264                  cout << "=> Joystick added to list." << endl;
    262265                #endif
    263266                        }
     
    265268                        {
    266269                #ifdef OIS_LINUX_JOY_DEBUG
    267                   std::cout << "\n__Not a joystick!!";
     270                  cout << "=> Not a joystick." << endl;
    268271                #endif
    269272                                close(fd);
     
    273276                {
    274277            #ifdef OIS_LINUX_JOY_DEBUG
    275               std::cout << "\nException caught!!";
     278              cout << "Exception caught!!" << endl;
    276279            #endif
    277280                        close(fd);
  • code/branches/resource2/src/ois/win32/Win32ForceFeedback.cpp

    r1505 r5668  
    2525#include <Math.h>
    2626
    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>
    2832  #include <sstream>
     33  using namespace std;
    2934#endif
    3035
     
    3237
    3338//--------------------------------------------------------------//
    34 Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* joy) :
    35         mHandles(0), mJoyStick(joy)
    36 {
     39Win32ForceFeedback::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
    3747}
    3848
     
    4555                LPDIRECTINPUTEFFECT dxEffect = i->second;
    4656                if( dxEffect )
     57                {
    4758                        dxEffect->Unload();
     59                        dxEffect->Release();
     60                }
    4861        }
    4962
    5063        mEffectList.clear();
     64}
     65
     66//--------------------------------------------------------------//
     67short Win32ForceFeedback::getFFAxesNumber()
     68{
     69        return mFFAxes;
     70}
     71
     72//--------------------------------------------------------------//
     73unsigned 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;
    5192}
    5293
     
    86127                        //have been unlaoded
    87128                        if( SUCCEEDED(dxEffect->Unload()) )
     129                        {
     130                            dxEffect->Release();
    88131                                mEffectList.erase(i);
     132                        }
    89133                }
    90134                else
     
    111155        DIPropGain.dwData            = gain_level;
    112156
    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
    114168}
    115169
     
    117171void Win32ForceFeedback::setAutoCenterMode( bool auto_on )
    118172{
    119         //DI Property DIPROPAUTOCENTER_OFF = 0, 1 is on
    120173        DIPROPDWORD DIPropAutoCenter;
    121174        DIPropAutoCenter.diph.dwSize       = sizeof(DIPropAutoCenter);
     
    123176        DIPropAutoCenter.diph.dwObj        = 0;
    124177        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
    129191}
    130192
     
    132194void Win32ForceFeedback::_updateConstantEffect( const Effect* effect )
    133195{
     196        ConstantEffect *eff = static_cast<ConstantEffect*>(effect->getForceEffect());
     197
    134198        DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    135199        LONG            rglDirection[2] = { 0, 0 };
     200        DIENVELOPE      diEnvelope;
    136201        DICONSTANTFORCE cf;
    137202        DIEFFECT        diEffect;
     
    139204        //Currently only support 1 axis
    140205        //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);
    144214        _upload(GUID_ConstantForce, &diEffect, effect);
    145215}
     
    148218void Win32ForceFeedback::_updateRampEffect( const Effect* effect )
    149219{
     220        RampEffect *eff = static_cast<RampEffect*>(effect->getForceEffect());
     221
    150222        DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    151223        LONG            rglDirection[2] = { 0, 0 };
     224        DIENVELOPE      diEnvelope;
    152225        DIRAMPFORCE     rf;
    153226        DIEFFECT        diEffect;
    154227
    155228        //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 );
    160233        _upload(GUID_RampForce, &diEffect, effect);
    161234}
     
    164237void Win32ForceFeedback::_updatePeriodicEffect( const Effect* effect )
    165238{
     239        PeriodicEffect *eff = static_cast<PeriodicEffect*>(effect->getForceEffect());
     240
    166241        DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    167242        LONG            rglDirection[2] = { 0, 0 };
     243        DIENVELOPE      diEnvelope;
    168244        DIPERIODIC      pf;
    169245        DIEFFECT        diEffect;
    170246
    171247        //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 );
    178254
    179255        switch( effect->type )
     
    191267void Win32ForceFeedback::_updateConditionalEffect( const Effect* effect )
    192268{
     269        ConditionalEffect *eff = static_cast<ConditionalEffect*>(effect->getForceEffect());
     270
    193271        DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    194272        LONG            rglDirection[2] = { 0, 0 };
     273        DIENVELOPE      diEnvelope;
    195274        DICONDITION     cf;
    196275        DIEFFECT        diEffect;
    197276
    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 );
    206285
    207286        switch( effect->type )
     
    218297void Win32ForceFeedback::_updateCustomEffect( const Effect* /*effect*/ )
    219298{
     299    //CustomEffect *eff = static_cast<CustomEffect*>(effect->getForceEffect());
     300    //
    220301        //DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
    221302        //LONG            rglDirection[2] = { 0, 0 };
     303        //DIENVELOPE      diEnvelope;
    222304        //DICUSTOMFORCE cf;
    223305        //DIEFFECT        diEffect;
     
    226308        //cf.cSamples = 0;
    227309        //cf.rglForceData = 0;
    228         //_setCommonProperties(&diEffect, rgdwAxes, rglDirection, sizeof(DICUSTOMFORCE), &cf, effect);
     310        //_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICUSTOMFORCE), &cf, effect, &eff->envelope);
    229311        //_upload(GUID_CustomForce, &diEffect, effect);
    230312}
     
    233315void Win32ForceFeedback::_setCommonProperties(
    234316                DIEFFECT* diEffect, DWORD* rgdwAxes,
    235                 LONG* rglDirection, DWORD 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 )
    237319{
    238320        ZeroMemory(diEffect, sizeof(DIEFFECT));
     
    240322        diEffect->dwSize                  = sizeof(DIEFFECT);
    241323        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;
    242378        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
    251389        diEffect->cbTypeSpecificParams    = struct_size;
    252390        diEffect->lpvTypeSpecificParams   = struct_type;
    253         diEffect->dwStartDelay            = effect->replay_delay;
    254391}
    255392
     
    295432void Win32ForceFeedback::_addEffectSupport( LPCDIEFFECTINFO pdei )
    296433{
    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
    300502        if( pdei->guid == GUID_ConstantForce )
    301                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Constant );
     503                _addEffectTypes(eForce, Effect::Constant );
    302504        else if( pdei->guid == GUID_Triangle )
    303                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Triangle );
     505                _addEffectTypes(eForce, Effect::Triangle );
    304506        else if( pdei->guid == GUID_Spring )
    305                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Spring );
     507                _addEffectTypes(eForce, Effect::Spring );
    306508        else if( pdei->guid == GUID_Friction )
    307                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Friction );
     509                _addEffectTypes(eForce, Effect::Friction );
    308510        else if( pdei->guid == GUID_Square )
    309                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Square );
     511                _addEffectTypes(eForce, Effect::Square );
    310512        else if( pdei->guid == GUID_Sine )
    311                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Sine );
     513                _addEffectTypes(eForce, Effect::Sine );
    312514        else if( pdei->guid == GUID_SawtoothUp )
    313                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothUp );
     515                _addEffectTypes(eForce, Effect::SawToothUp );
    314516        else if( pdei->guid == GUID_SawtoothDown )
    315                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::SawToothDown );
     517                _addEffectTypes(eForce, Effect::SawToothDown );
    316518        else if( pdei->guid == GUID_Damper )
    317                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Damper );
     519                _addEffectTypes(eForce, Effect::Damper );
    318520        else if( pdei->guid == GUID_Inertia )
    319                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Inertia );
     521                _addEffectTypes(eForce, Effect::Inertia );
    320522        else if( pdei->guid == GUID_CustomForce )
    321                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Custom );
     523                _addEffectTypes(eForce, Effect::Custom );
    322524        else if( pdei->guid == GUID_RampForce )
    323                 _addEffectTypes((Effect::EForce)DIEFT_GETTYPE(pdei->dwEffType), Effect::Ramp );
     525                _addEffectTypes(eForce, Effect::Ramp );
     526
    324527#if defined (_DEBUG)
    325528        //Only care about this for Debugging Purposes
     
    333536#endif
    334537}
     538
     539//--------------------------------------------------------------//
     540void Win32ForceFeedback::_addFFAxis()
     541{
     542        mFFAxes++;
     543}
  • code/branches/resource2/src/ois/win32/Win32ForceFeedback.h

    r1505 r5668  
    3434                Win32ForceFeedback() {}
    3535        public:
    36                 Win32ForceFeedback(IDirectInputDevice8* joy);
     36                Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps);
    3737                ~Win32ForceFeedback();
    3838
     
    5252                void setAutoCenterMode( bool auto_on );
    5353
    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();
    5859
    5960                /**
     
    6465                void _addEffectSupport( LPCDIEFFECTINFO pdei );
    6566
     67                /**
     68                        @remarks
     69                        Internal use.. Used during axis enumeration to get number of FF axes
     70                        support effects.
     71                */
     72                void _addFFAxis();
     73
    6674        protected:
     75
    6776                //Specific Effect Settings
    6877                void _updateConstantEffect( const Effect* effect );
     
    7180                void _updateConditionalEffect( const Effect* effect );
    7281                void _updateCustomEffect( const Effect* effect );
     82
    7383                //Sets the common properties to all effects
    7484                void _setCommonProperties( DIEFFECT* diEffect, DWORD* rgdwAxes,
    75                                                                         LONG* rglDirection, DWORD 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 );
    7787                //Actually do the upload
    7888                void _upload( GUID, DIEFFECT*, const Effect* );
    7989
     90                // Map of currently uploaded effects (handle => effect)
    8091                typedef std::map<int,LPDIRECTINPUTEFFECT> EffectList;
    8192                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
    8395                //during the lifetime of application. Hopefully, that is enough.
    8496                int mHandles;
    8597
     98                // Joystick device descriptor.
    8699                IDirectInputDevice8* mJoyStick;
     100               
     101                // Joystick capabilities.
     102                const DIDEVCAPS* mpDIJoyCaps;
     103
     104                // Number of axis supporting FF.
     105                short mFFAxes;
    87106        };
    88107}
  • code/branches/resource2/src/ois/win32/Win32InputManager.cpp

    r1505 r5668  
    7575        hInst = GetModuleHandle(0);
    7676
    77         //Create the device
     77        //Create the input system
    7878        hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL );
    7979    if (FAILED(hr))     
     
    8282        //Ok, now we have DirectInput, parse whatever extra settings were sent to us
    8383        _parseConfigSettings( paramList );
     84
     85        // Enumerate devices ...
    8486        _enumerateDevices();
    8587}
     
    116118{
    117119        //Enumerate all attached devices
    118         mDirectInput->EnumDevices(NULL, _DIEnumKbdCallback, this, DIEDFL_ATTACHEDONLY);
    119 }
    120 
    121 //--------------------------------------------------------------------------------//
    122 BOOL CALLBACK Win32InputManager::_DIEnumKbdCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
     120        mDirectInput->EnumDevices(NULL , _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY);
     121}
     122
     123//--------------------------------------------------------------------------------//
     124BOOL CALLBACK Win32InputManager::_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
    123125{
    124126        Win32InputManager *_this_ = static_cast<Win32InputManager*>(pvRef);
     127
     128        // Register only game devices (keyboard and mouse are managed differently).
    125129        if( GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK ||
    126130                GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD ||
  • code/branches/resource2/src/ois/win32/Win32InputManager.h

    r1505 r5668  
    8181
    8282                //! Used during device enumeration
    83                 static BOOL CALLBACK _DIEnumKbdCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
     83                static BOOL CALLBACK _DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
    8484
    8585                //! Keep a list of all joysticks enumerated, but not in use
  • code/branches/resource2/src/ois/win32/Win32JoyStick.cpp

    r1505 r5668  
    8282        mState.mAxes.clear();
    8383
    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.
    87104        DIPROPDWORD dipdw;
    88 
    89105        dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
    90106        dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
     
    93109        dipdw.dwData            = JOYSTICK_DX_BUFFERSIZE;
    94110
    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 
    106111        if( FAILED(mJoyStick->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) )
    107                 OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set buffer size property" );
    108 
    109         //Enumerate all axes/buttons/sliders/etc before aquiring
     112                OIS_EXCEPT( E_General, "Win32JoyStick::_initialize >> Failed to set buffer size property" );
     113
     114        // Enumerate all axes/buttons/sliders/force feedback/etc before aquiring
    110115        _enumerate();
    111116
     
    118123void Win32JoyStick::_enumerate()
    119124{
    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);
    129139
    130140        //Reset the axis mapping enumeration value
    131141        _AxisNumber = 0;
    132142
    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)
    137144        mJoyStick->EnumObjects(DIEnumDeviceObjectsCallback, this, DIDFT_AXIS);
    138145}
     
    181188                OIS_EXCEPT( E_General, "Win32JoyStick::_DIEnumDeviceObjectsCallback >> Failed to set min/max range property" );
    182189
    183         //Check if FF Axes
     190        //Check if FF Axes, and if so, increment counter
    184191        if((lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 )
    185192        {
    186193                if( _this->ff_device )
    187194                {
    188                         //todo - increment force feedback axis count
     195                        _this->ff_device->_addFFAxis();
    189196                }
    190197        }
    191198
     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
    192208        return DIENUM_CONTINUE;
    193209}
     
    198214        Win32JoyStick* _this = (Win32JoyStick*)pvRef;
    199215
    200         //Create the FF class after we know there is at least one effect type
     216        //Create the FF instance only after we know there is at least one effect type
    201217        if( _this->ff_device == 0 )
    202                 _this->ff_device = new Win32ForceFeedback(_this->mJoyStick);
     218          _this->ff_device = new Win32ForceFeedback(_this->mJoyStick, &_this->mDIJoyCaps);
    203219
    204220        _this->ff_device->_addEffectSupport( pdei );
  • code/branches/resource2/src/ois/win32/Win32JoyStick.h

    r1505 r5668  
    6060                IDirectInput8* mDirectInput;
    6161                IDirectInputDevice8* mJoyStick;
     62                DIDEVCAPS mDIJoyCaps;
     63
    6264                DWORD coopSetting;
    6365                GUID deviceGuid;
  • code/branches/resource2/src/ois/win32/Win32KeyBoard.cpp

    r1505 r5668  
    238238                return 0;
    239239
    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
    244243        if(ascii == 1 && deadKey != '\0' )
    245244        {
Note: See TracChangeset for help on using the changeset viewer.