Sign in to follow this  

DirectInput/Force Feedback question...

This topic is 3738 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

Hello all, longtime reader, first time poster :p I've been working in C# for DirectX 9.0 in Visual Studio .Net, trying to work with force feedback via a MS Sidewinder joystick. I've culled code mostly from the MSDN knowledge base. I can upload an effect and I can read all of the buttons and axis info (took me a while to discover "polling", lol) but I can't for the life of me get an effect to play immediately after a button is pressed... it only seems to play when the joystick has been moved a little bit, causing something on the joystick called "SafetySwitchOn" to be enabled... it's weird. Anyway, I think/hope this is a simple question to answer. This is what code I have, if it helps:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectInput;

namespace JoystickProject
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Label label1;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;
		private Device device = null;
		private bool running = true;
		private ArrayList effectList = new ArrayList();
		private bool button0pressed = false;
		private string joyState = "";

		public bool InitializeInput()
		{
			// Create our joystick device
			foreach(DeviceInstance di in Manager.GetDevices(DeviceClass.GameControl,
				EnumDevicesFlags.AttachedOnly | EnumDevicesFlags.ForceFeeback))
			{
				// Pick the first attached joystick we see
				device = new Device(di.InstanceGuid);
				break;
			}
			if (device == null) // We couldn't find a joystick
				return false;

			device.SetDataFormat(DeviceDataFormat.Joystick);
			device.SetCooperativeLevel(this, CooperativeLevelFlags.Background |
				CooperativeLevelFlags.Exclusive);
			device.Properties.AxisModeAbsolute = true;
			device.Properties.AutoCenter = true;
			device.Acquire();

			// Enumerate any axes
			foreach(DeviceObjectInstance doi in device.Objects)
			{
				if ((doi.ObjectId & (int)DeviceObjectTypeFlags.Axis) != 0)
				{
					// We found an axis, set the range to a max of 10,000
					device.Properties.SetRange(ParameterHow.ById,
						doi.ObjectId, new InputRange(-5000, 5000));
				}
			}

			// Load our feedback file
			EffectList effects = null;
			effects = device.GetEffects(@"C:\Documents and Settings\staton\Desktop\FFEffects\guna.ffe",
				FileEffectsFlags.ModifyIfNeeded);
			foreach(FileEffect fe in effects)
			{
				EffectObject myEffect = new EffectObject(fe.EffectGuid, fe.EffectStruct,
					device);
				myEffect.Download();
				effectList.Add(myEffect);
			}

			while(running)
			{
				UpdateInputState();
				Application.DoEvents();
			}

			return true;
		}

		private void PlayEffects()
		{
				// See if our effects are playing.
				foreach(EffectObject myEffect in effectList)
				{
					//if (button0pressed == true)
					//{
						//MessageBox.Show("Button Pressed.");
					//	myEffect.Start(1, EffectStartFlags.NoDownload);
					//}

					if (!myEffect.EffectStatus.Playing)
					{
						// If not, play them
						myEffect.Start(1, EffectStartFlags.NoDownload);
					}
				}
				button0pressed = false;
		}

		protected override void OnClosed(EventArgs e)
		{
			running = false;
		}

		private void UpdateInputState()
		{
			PlayEffects();

			// Check the joystick state
			JoystickState state = device.CurrentJoystickState;
			device.Poll();
			joyState = "Using JoystickState: \r\n";

			joyState += device.Properties.ProductName;
			joyState += "\n";
			joyState += device.ForceFeedbackState;
			joyState += "\n";
			joyState += state.ToString();

			byte[] buttons = state.GetButtons();
			for(int i = 0; i < buttons.Length; i++)
				joyState += string.Format("Button {0} {1}\r\n", i, buttons[i] != 0 ? "Pressed" : "Not Pressed");

			label1.Text = joyState;

			if(buttons[0] != 0)
				button0pressed = true;
			
		}

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.label1 = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// label1
			// 
			this.label1.BackColor = System.Drawing.SystemColors.ActiveCaptionText;
			this.label1.Location = new System.Drawing.Point(8, 8);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(272, 488);
			this.label1.TabIndex = 0;
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.BackColor = System.Drawing.SystemColors.ControlText;
			this.ClientSize = new System.Drawing.Size(288, 502);
			this.Controls.AddRange(new System.Windows.Forms.Control[] {
																		  this.label1});
			this.Name = "Form1";
			this.Text = "Joystick Stuff";
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			using (Form1 frm = new Form1())
			{
				frm.Show();
				if (!frm.InitializeInput())
					MessageBox.Show("Couldn't find a joystick.");
			}
		}
	}
}



Thanks in advance! -John

Share this post


Link to post
Share on other sites
From the sound of it, this is by design for the hardware. Googling for 'force feedback safety switch' gives me a patent:

Quote:

A force feedback interface device including safety features. The interface device includes a sensor that senses the position of a user manipulatable object in a degree of freedom and provides a sensor signal indicating the position of the user manipulatable object to a host computer. An actuator of the device applies a force to the user manipulatable object in the degree of freedom. A safety switch of the interface device disables the actuator when the user is not using the interface device and enables the actuator when the user is using the device. A device is included in the interface device to execute a force ramping process when the safety switch enables the actuator, the force ramping process causing the force to be produced at a reduced magnitude and slowly increased to a desired magnitude over a period of time to avoid an abrupt application of initial force.


That sounds like the switch will stop feedback from being applied when the stick is not "in use," i.e. the user is not pushing it in any direction.

Share this post


Link to post
Share on other sites
Solution found!

For future reference, the SafetySwitch is controlled by a small LED/distance sensor at the base of the joystick handle. If a hand is on the stick, then the SafetySwitch is on and the force feedback effect can be played, if not, then no effect can be played. With this knowledge, I actually finally do have an effect played at the touch of the trigger, and it stops when the trigger is released, and everything is as it should be. Woot!

Share this post


Link to post
Share on other sites

This topic is 3738 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this