// Note that this does not appear to work at this time. I probably need to have more infos. public void SetVibration(int left, int right) { // my first clue that it doesn't work is that LEFT and RIGHT _AREN'T USED_ // I should just look for C++ examples instead of trying to look for SlimDX examples var parameters = new EffectParameters { Duration = 0x2710, Gain = 0x2710, SamplePeriod = 0, TriggerButton = 0, TriggerRepeatInterval = 0x2710, Flags = EffectFlags.None }; parameters.GetAxes(out var temp1, out var temp2); parameters.SetAxes(temp1, temp2); var effect = new Effect(_joystick, EffectGuid.ConstantForce); effect.SetParameters(parameters); effect.Start(1); }
/// <summary> /// Creates an FFB effect, stores it at a given slot and starts its playback. /// </summary> /// <param name="data"> /// Parameters of the effect to be created. /// </param> /// <returns> /// Returns true if successful, otherwise returns false. /// </returns> public bool SendFFBEffect(DataClasses.FFBEffectData data) { //Check if the device is properly initialized if (ffbDevice == null) { MessageBox.Show("Device not initialized.", FFBInspector.Properties.Resources.errCap_devError, MessageBoxButtons.OK, MessageBoxIcon.Stop); return(false); } //If there is an effect already stored in this slot, remove it StopOneEffect(data.slot); int[] axes = new Int32[actuatorsObjectTypes.Count]; int i = 0; foreach (int objt in actuatorsObjectTypes) { axes[i++] = objt; } //Set effect direction int[] dirs = data.effect.GetDirections(); //Set the general effect parameters up EffectParameters eParams = new EffectParameters(); eParams.Duration = data.effect.duration; eParams.Flags = EffectFlags.Cartesian | EffectFlags.ObjectIds; eParams.Gain = data.effect.gain; eParams.SetAxes(axes, dirs); eParams.StartDelay = data.effect.startDelay; eParams.SamplePeriod = 0; //Use the default sample period; eParams.TriggerButton = data.effect.trigButton; eParams.TriggerRepeatInterval = data.effect.trigRepInterval; //Set the type specific effect parameters up TypeSpecificParameters typeSpec = null; if (data.effect.effectGuid == EffectGuid.ConstantForce) { DataClasses.ConstantEffectTypeData cfEfd = (DataClasses.ConstantEffectTypeData)data.effect; typeSpec = new ConstantForce(); typeSpec.AsConstantForce().Magnitude = cfEfd.magnitude; } else if (data.effect.effectGuid == EffectGuid.RampForce) { DataClasses.RampEffectTypeData rfEfd = (DataClasses.RampEffectTypeData)data.effect; typeSpec = new RampForce(); typeSpec.AsRampForce().Start = rfEfd.start; typeSpec.AsRampForce().End = rfEfd.end; } else if (data.effect.effectGuid == EffectGuid.Sine || data.effect.effectGuid == EffectGuid.Triangle || data.effect.effectGuid == EffectGuid.Square || data.effect.effectGuid == EffectGuid.SawtoothUp || data.effect.effectGuid == EffectGuid.SawtoothDown) { DataClasses.PeriodicEffectTypeData pfEfd = (DataClasses.PeriodicEffectTypeData)data.effect; typeSpec = new PeriodicForce(); typeSpec.AsPeriodicForce().Magnitude = pfEfd.magnitude; typeSpec.AsPeriodicForce().Offset = pfEfd.offset; typeSpec.AsPeriodicForce().Period = pfEfd.period; typeSpec.AsPeriodicForce().Phase = pfEfd.phase; } else if (data.effect.effectGuid == EffectGuid.Friction || data.effect.effectGuid == EffectGuid.Inertia || data.effect.effectGuid == EffectGuid.Damper || data.effect.effectGuid == EffectGuid.Spring) { DataClasses.ConditionEffectTypeData cdEfd = (DataClasses.ConditionEffectTypeData)data.effect; typeSpec = new ConditionSet(); typeSpec.AsConditionSet().Conditions = new Condition[1]; typeSpec.AsConditionSet().Conditions[0].DeadBand = cdEfd.deadBand; typeSpec.AsConditionSet().Conditions[0].Offset = cdEfd.offset; typeSpec.AsConditionSet().Conditions[0].NegativeCoefficient = cdEfd.negCoeff; typeSpec.AsConditionSet().Conditions[0].NegativeSaturation = cdEfd.negSat; typeSpec.AsConditionSet().Conditions[0].PositiveCoefficient = cdEfd.posCoeff; typeSpec.AsConditionSet().Conditions[0].PositiveSaturation = cdEfd.posSat; } eParams.Parameters = typeSpec; //Create an envelope if (data.envelope != null) { Envelope envp = new Envelope(); envp.AttackLevel = data.envelope.attackLevel; envp.AttackTime = data.envelope.attackTime; envp.FadeLevel = data.envelope.fadeLevel; envp.FadeTime = data.envelope.fadeTime; eParams.Envelope = envp; } //Create an effect and add it to the list Effect ef; try { ef = new Effect(ffbDevice, data.effect.effectGuid, eParams); ffbEffects[data.slot] = ef; } catch (Exception ex) { MessageBox.Show("Cannot create effect.\n" + ex.Message + "\n" + ex.Data, FFBInspector.Properties.Resources.errCap_effError, MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } return(StartFFBEffect(ef)); }
/// <summary> /// Creates an FFB effect, stores it at a given slot and starts its playback. /// </summary> /// <param name="data"> /// Parameters of the effect to be created. /// </param> /// <returns> /// Returns true if successful, otherwise returns false. /// </returns> public bool SendFFBEffect(DataClasses.FFBEffectData data) { //Check if the device is properly initialized if (ffbDevice == null) { MessageBox.Show("Device not initialized.", FFBInspector.Properties.Resources.errCap_devError, MessageBoxButtons.OK, MessageBoxIcon.Stop); return false; } //If there is an effect already stored in this slot, remove it StopOneEffect(data.slot); int[] axes = new Int32[actuatorsObjectTypes.Count]; int i = 0; foreach (int objt in actuatorsObjectTypes) { axes[i++] = objt; } //Set effect direction int[] dirs = data.effect.GetDirections(); //Set the general effect parameters up EffectParameters eParams = new EffectParameters(); eParams.Duration = data.effect.duration; eParams.Flags = EffectFlags.Cartesian | EffectFlags.ObjectIds; eParams.Gain = data.effect.gain; eParams.SetAxes(axes, dirs); eParams.StartDelay = data.effect.startDelay; eParams.SamplePeriod = 0; //Use the default sample period; eParams.TriggerButton = data.effect.trigButton; eParams.TriggerRepeatInterval = data.effect.trigRepInterval; //Set the type specific effect parameters up TypeSpecificParameters typeSpec = null; if (data.effect.effectGuid == EffectGuid.ConstantForce) { DataClasses.ConstantEffectTypeData cfEfd = (DataClasses.ConstantEffectTypeData)data.effect; typeSpec = new ConstantForce(); typeSpec.AsConstantForce().Magnitude = cfEfd.magnitude; } else if (data.effect.effectGuid == EffectGuid.RampForce) { DataClasses.RampEffectTypeData rfEfd = (DataClasses.RampEffectTypeData)data.effect; typeSpec = new RampForce(); typeSpec.AsRampForce().Start = rfEfd.start; typeSpec.AsRampForce().End = rfEfd.end; } else if (data.effect.effectGuid == EffectGuid.Sine || data.effect.effectGuid == EffectGuid.Triangle || data.effect.effectGuid == EffectGuid.Square || data.effect.effectGuid == EffectGuid.SawtoothUp || data.effect.effectGuid == EffectGuid.SawtoothDown) { DataClasses.PeriodicEffectTypeData pfEfd = (DataClasses.PeriodicEffectTypeData)data.effect; typeSpec = new PeriodicForce(); typeSpec.AsPeriodicForce().Magnitude = pfEfd.magnitude; typeSpec.AsPeriodicForce().Offset = pfEfd.offset; typeSpec.AsPeriodicForce().Period = pfEfd.period; typeSpec.AsPeriodicForce().Phase = pfEfd.phase; } else if (data.effect.effectGuid == EffectGuid.Friction || data.effect.effectGuid == EffectGuid.Inertia || data.effect.effectGuid == EffectGuid.Damper || data.effect.effectGuid == EffectGuid.Spring) { DataClasses.ConditionEffectTypeData cdEfd = (DataClasses.ConditionEffectTypeData)data.effect; typeSpec = new ConditionSet(); typeSpec.AsConditionSet().Conditions = new Condition[1]; typeSpec.AsConditionSet().Conditions[0].DeadBand = cdEfd.deadBand; typeSpec.AsConditionSet().Conditions[0].Offset = cdEfd.offset; typeSpec.AsConditionSet().Conditions[0].NegativeCoefficient = cdEfd.negCoeff; typeSpec.AsConditionSet().Conditions[0].NegativeSaturation = cdEfd.negSat; typeSpec.AsConditionSet().Conditions[0].PositiveCoefficient = cdEfd.posCoeff; typeSpec.AsConditionSet().Conditions[0].PositiveSaturation = cdEfd.posSat; } eParams.Parameters = typeSpec; //Create an envelope if (data.envelope != null) { Envelope envp = new Envelope(); envp.AttackLevel = data.envelope.attackLevel; envp.AttackTime = data.envelope.attackTime; envp.FadeLevel = data.envelope.fadeLevel; envp.FadeTime = data.envelope.fadeTime; eParams.Envelope = envp; } //Create an effect and add it to the list Effect ef; try { ef = new Effect(ffbDevice, data.effect.effectGuid, eParams); ffbEffects[data.slot] = ef; } catch (Exception ex) { MessageBox.Show("Cannot create effect.\n" + ex.Message + "\n" + ex.Data, FFBInspector.Properties.Resources.errCap_effError, MessageBoxButtons.OK, MessageBoxIcon.Error); return false; } return StartFFBEffect(ef); }
// Note that this does not appear to work at this time. I probably need to have more infos. public void SetVibration(int left, int right) { int[] temp1, temp2; // my first clue that it doesnt work is that LEFT and RIGHT _ARENT USED_ // I should just look for C++ examples instead of trying to look for SlimDX examples var parameters = new EffectParameters { Duration = 0x2710, Gain = 0x2710, SamplePeriod = 0, TriggerButton = 0, TriggerRepeatInterval = 0x2710, Flags = EffectFlags.None }; parameters.GetAxes(out temp1, out temp2); parameters.SetAxes(temp1, temp2); var effect = new Effect(joystick, EffectGuid.ConstantForce); effect.SetParameters(parameters); effect.Start(1); }
/// <summary> /// Initializes force feedback. /// </summary> /// <param name="device">The device representing the joystick.</param> /// <param name="xAxisOffset">The id of the x axis-providing device.</param> /// <param name="yAxisOffset">The id of the y axis-providing device.</param> /// <param name="numAxes"></param> /// <returns>True if force feedback could be initialized, false otherwise.</returns> public static bool dInputInitFD(Device device, int xAxisOffset, int yAxisOffset, int numAxes) { try { Guid forceFeedbackGuid = Guid.Empty; forceFeedbackGuid = EffectGuid.ConstantForce; int[] offsets = null; int[] coords = null; if (numAxes == 1) { offsets = new int[1]; offsets[0] = xAxisOffset; coords = new int[1]; } else { offsets = new int[2]; offsets[0] = xAxisOffset; offsets[1] = yAxisOffset; coords = new int[2]; } //offsets[0] = 4; //offsets[1] = 0; for (int i = 0; i < coords.Length; i++) { coords[i] = 0; } EffectParameters info = new EffectParameters(); info.Flags = EffectFlags.Polar | EffectFlags.ObjectIds; ConstantForce typeSpec = new ConstantForce(); typeSpec.Magnitude = 5000; info.Duration = -1; info.SamplePeriod = 0; info.Parameters = typeSpec; info.TriggerButton = -1; info.TriggerRepeatInterval = 0; info.Gain = 5000; info.SetAxes(offsets, coords); info.StartDelay = 0; Envelope env = new Envelope(); env.AttackLevel = 10000; env.AttackTime = 0; env.FadeLevel = 10000; env.FadeTime = 0; info.Envelope = null; afterburnerEffect = new Effect(device, EffectGuid.ConstantForce, info); ConstantForce gFTypeSpec = new ConstantForce(); gFTypeSpec.Magnitude = 3000; info = new EffectParameters(); info.SamplePeriod = 0; info.Parameters = gFTypeSpec; info.TriggerButton = -1; info.TriggerRepeatInterval = -1; info.Gain = 3000; info.Flags = EffectFlags.Polar | EffectFlags.ObjectIds; info.SetAxes(offsets, coords); info.StartDelay = 0; info.Envelope = null; info.Duration = -1; gForceEffect = new Effect(device, EffectGuid.ConstantForce, info); env.AttackLevel = 0; //this is +parameter.magnitude env.AttackTime = 0; env.FadeLevel = 10000; env.FadeTime = 2000000; //How long it will take effect to reach fadeLevel info.Envelope = env; ConstantForce cmType = new ConstantForce(); cmType.Magnitude = 3000; info.Parameters = cmType; info.Duration = 1000000; //at sustained level info.Gain = 3000; cruiseMissileEffect = new Effect(device, EffectGuid.ConstantForce, info); ConstantForce fType = new ConstantForce(); fType.Magnitude = 3000; info.Duration = 50000; info.Gain = 3000; info.Parameters = fType; info.Envelope = null; fireEffect = new Effect(device, EffectGuid.ConstantForce, info); ConstantForce eType = new ConstantForce(); eType.Magnitude = 10000; info.Parameters = eType; info.Gain = 10000; info.Duration = 0; env.AttackTime = 0; env.AttackLevel = 0; env.FadeTime = 7000000; env.FadeLevel = 3000; info.Envelope = env; explodeEffect = new Effect(device, EffectGuid.ConstantForce, info); ConstantForce hType = new ConstantForce(); hType.Magnitude = 3200; info.Parameters = hType; info.Gain = 3200; info.Duration = 100000; info.Envelope = null; hitEffect = new Effect(device, EffectGuid.ConstantForce, info); return(true); } catch { return(false); } }
//move all the FFB gibberish into a method so i can actually see whats going on in Start() public void FFBStart() { // Find an FFB wheel and hook it DirectInput directInput = new DirectInput(); var ret = directInput.GetDevices(DeviceClass.GameControl, DeviceEnumerationFlags.ForceFeedback); if (ret.Count > 0) { steeringWheel = ret[0]; steeringWheelJoy = new Joystick(directInput, steeringWheel.InstanceGuid); steeringWheelJoy.SetCooperativeLevel(GetWindowHandle(), CooperativeLevel.Exclusive | CooperativeLevel.Background); steeringWheelJoy.Properties.AutoCenter = true; steeringWheelJoy.Acquire(); List <int> actuatorsObjectTypes = new List <int>(); //Get all available force feedback actuators foreach (DeviceObjectInstance doi in steeringWheelJoy.GetObjects()) { if ((doi.ObjectId.Flags & DeviceObjectTypeFlags.ForceFeedbackActuator) != 0) { actuatorsObjectTypes.Add((int)doi.ObjectId.Flags); } } axes = new Int32[actuatorsObjectTypes.Count]; int i = 0; foreach (int objt in actuatorsObjectTypes) { axes[i++] = objt; } //Set effect direction dirs = new int[] { 1 }; ffbForce = new SharpDX.DirectInput.ConstantForce { Magnitude = 0 }; var ep = new EffectParameters { Duration = -1, Flags = EffectFlags.Cartesian | EffectFlags.ObjectIds, Gain = 10000, StartDelay = 0, SamplePeriod = 0, TriggerButton = -1, TriggerRepeatInterval = 0 }; ep.SetAxes(axes, dirs); ep.Parameters = ffbForce; var allEffects = steeringWheelJoy.GetEffects(); foreach (var effectInfo in allEffects) { if (effectInfo.Name.Contains("Constant")) { constantForceEffect = effectInfo; } } ffbeffect = new Effect(steeringWheelJoy, constantForceEffect.Guid, ep); ffbeffect.Start(); } }