Jump to content
  • Advertisement
Sign in to follow this  
JeroMiya007

Force Feedback Rumble in managed DirectInput

This topic is 3978 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm using Xna, but unfortunately it doesn't support 3rd party gamepads on windows. I used Soopah's input library to get the gamepads working in Xna (Soopah's library uses managed DirectInput), however it doesn't support the "rumbling" force feedback effects, so i decided to try to add support for force feedback rumbling. Soopah's library can be found here: http://sourceforge.net/projects/xnadirectinput/ I've used the code from MSDN (with a Logitech wired Rumblepad 2 gamepad), however it doesn't work at all. It throws exceptions (I've made notes of the lines that throw exceptions in the comments). Here is the method that initializes force feedback (this is added to Soopah's DirectInputGamepad class. device is the DirectInput device of the gamepad):
        /// <summary>
        /// A list of axis for the force feedback effect
        /// </summary>
        int[] axis = null;

        /// <summary>
        /// Initialize force feedback, if available.
        /// Code mostly from MSDN article
        /// URL: http://msdn2.microsoft.com/en-us/library/bb153254.aspx
        /// </summary>
        public void InitializeForceFeedback()
        {
            // check that it supports force feedback
            if (SupportsForceFeedback())
            {
                if (!wndSet)
                    throw new Exception("hWnd must be set before initializing forcefeedback on a gamepad");

                // must set the cooperative level to exclusive for force feedback to work
                this.device.SetCooperativeLevel(DirectInputGamepad.hWnd,
                    Microsoft.DirectX.DirectInput.CooperativeLevelFlags.Exclusive |
                    Microsoft.DirectX.DirectInput.CooperativeLevelFlags.Background);

                //Acquire joystick for capturing (possibly not needed).
                // ERROR: The following line is in the sample code, but
                //  if uncommented the AxisModeAbsolute setting line after
                //  it throws an AcquiredException, meaning it can't be done
                //  while the device is acquired.
                //device.Acquire();

                //Set axis mode absolute.
                device.Properties.AxisModeAbsolute = true;

                //Configure axes
                foreach (Microsoft.DirectX.DirectInput.DeviceObjectInstance doi in device.Objects)
                {
                    //Set axes ranges.
                    if ((doi.ObjectId & (int)Microsoft.DirectX.DirectInput.DeviceObjectTypeFlags.Axis) != 0)
                    {
                        device.Properties.SetRange(
                        Microsoft.DirectX.DirectInput.ParameterHow.ById,
                        doi.ObjectId,
                        new InputRange(0, 1000));
                    }

                    int[] temp;

                    // Get info about first two FF axii on the device
                    if ((doi.Flags & (int)Microsoft.DirectX.DirectInput.ObjectInstanceFlags.Actuator) != 0)
                    {
                        if (axis != null)
                        {
                            temp = new int[axis.Length + 1];
                            axis.CopyTo(temp, 0);
                            axis = temp;
                        }
                        else
                        {
                            axis = new int[1];
                        }

                        // Store the offset of each axis.
                        axis[axis.Length - 1] = doi.Offset;
                        if (axis.Length == 2)
                        {
                            // This line outputs "Found 2 force feedback axis: (8, 12): " with the
                            // Logitech Rumblepad 2 gamepad
                            System.Console.WriteLine("Found 2 force feedback axis: ({0}, {1}): ", axis[0], axis[1]);
                        }
                    }
                }
            }
        }
And here is the code that loads the effect and supposedly starts it:
        EffectObject eo = null;
        public void StartConstantForce()
        {
            // I tried this instead of the rest of the code here, but
            // it throws an "incomplete effect" exception when I try to
            // start the effect.
            //eo = new Microsoft.DirectX.DirectInput.EffectObject(ForceFeedbackGuid.Sine, device);
            
            //See if joystick supports ConstantForce and set it.
            Microsoft.DirectX.DirectInput.Effect e;

            foreach (Microsoft.DirectX.DirectInput.EffectInformation ei in 
                    device.GetEffects(Microsoft.DirectX.DirectInput.EffectType.All))
            {
                //If the joystick supports ConstantForce, then apply it.
                if (Microsoft.DirectX.DirectInput.DInputHelper.GetTypeCode(ei.EffectType)
                    == (int)Microsoft.DirectX.DirectInput.EffectType.ConstantForce)
                {
                    // Fill in some generic values for the effect.
                    e = new Microsoft.DirectX.DirectInput.Effect();
                    e.SetDirection(new int[axis.Length]);
                    e.SetAxes(new int[axis.Length]);
                    e.ConditionStruct = new Microsoft.DirectX.DirectInput.Condition[axis.Length];

                    e.EffectType = Microsoft.DirectX.DirectInput.EffectType.ConstantForce;
                    e.Duration = (int)DI.Infinite;
                    e.Gain = 10000;
                    e.SamplePeriod = 0;
                    e.TriggerButton = (int)Microsoft.DirectX.DirectInput.Button.NoTrigger;
                    e.TriggerRepeatInterval = (int)DI.Infinite;
                    e.Flags = Microsoft.DirectX.DirectInput.EffectFlags.ObjectOffsets |
                              Microsoft.DirectX.DirectInput.EffectFlags.Cartesian;
                    //e.SetAxes(axis);

                    // Create the effect, using the passed in guid.
                    // THROWS AN ERROR: Value not within expected range
                    eo = new Microsoft.DirectX.DirectInput.EffectObject(ei.EffectGuid, e, device);
                }
            }
            if (eo == null)
                throw new Exception("constant force effect not found");
        }

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!