JoystickDevice <WinMMJoyDetails> OpenJoystick(int number) { JoystickDevice <WinMMJoyDetails> stick = null; JoyCaps caps; JoystickError result = UnsafeNativeMethods.joyGetDevCaps(number, out caps, JoyCaps.SizeInBytes); if (result != JoystickError.NoError) { return(null); } int num_axes = caps.NumAxes; if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0) { num_axes += 2; } stick = new JoystickDevice <WinMMJoyDetails>(number, num_axes, caps.NumButtons); stick.Details = new WinMMJoyDetails(num_axes); // Make sure to reverse the vertical axes, so that +1 points up and -1 points down. int axis = 0; if (axis < caps.NumAxes) { stick.Details.Min[axis] = caps.XMin; stick.Details.Max[axis] = caps.XMax; axis++; } if (axis < caps.NumAxes) { stick.Details.Min[axis] = caps.YMax; stick.Details.Max[axis] = caps.YMin; axis++; } if (axis < caps.NumAxes) { stick.Details.Min[axis] = caps.ZMax; stick.Details.Max[axis] = caps.ZMin; axis++; } if (axis < caps.NumAxes) { stick.Details.Min[axis] = caps.RMin; stick.Details.Max[axis] = caps.RMax; axis++; } if (axis < caps.NumAxes) { stick.Details.Min[axis] = caps.UMin; stick.Details.Max[axis] = caps.UMax; axis++; } if (axis < caps.NumAxes) { stick.Details.Min[axis] = caps.VMax; stick.Details.Max[axis] = caps.VMin; axis++; } if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0) { stick.Details.PovType = PovType.Exists; if ((caps.Capabilities & JoystCapsFlags.HasPov4Dir) != 0) { stick.Details.PovType |= PovType.Discrete; } if ((caps.Capabilities & JoystCapsFlags.HasPovContinuous) != 0) { stick.Details.PovType |= PovType.Continuous; } } #warning "Implement joystick name detection for WinMM." stick.Description = String.Format("Joystick/Joystick #{0} ({1} axes, {2} buttons)", number, stick.Axis.Count, stick.Button.Count); // Todo: Try to get the device name from the registry. Oh joy! //string key_path = String.Format("{0}\\{1}\\{2}", RegistryJoyConfig, caps.RegKey, RegstryJoyCurrent); //RegistryKey key = Registry.LocalMachine.OpenSubKey(key_path, false); //if (key == null) // key = Registry.CurrentUser.OpenSubKey(key_path, false); //if (key == null) // stick.Description = String.Format("USB Joystick {0} ({1} axes, {2} buttons)", number, stick.Axis.Count, stick.Button.Count); //else //{ // key.Close(); //} if (stick != null) { Debug.Print("Found joystick on device number {0}", number); } return(stick); }
public JoystickState GetState(int player_index) { lock (sync) { JoystickState state = new JoystickState(); if (IsValid(player_index)) { int device_index = player_to_index[player_index]; int index = index_to_stick[device_index]; JoystickDevice <WinMMJoyDetails> stick = sticks[index] as JoystickDevice <WinMMJoyDetails>; // For joysticks with fewer than three axes or four buttons, we must // use joyGetPos; otherwise, joyGetPosEx. This is not just a cosmetic // difference, simple devices will return incorrect results if we use // joyGetPosEx on them. if (stick.Details.Capabilities.AxisCount <= 3 || stick.Details.Capabilities.ButtonCount <= 4) { // Use joyGetPos JoyInfo info = new JoyInfo(); JoystickError result = UnsafeNativeMethods.joyGetPos(device_index, ref info); if (result == JoystickError.NoError) { for (int i = 0; i < stick.Details.Capabilities.AxisCount; i++) { state.SetAxis(JoystickAxis.Axis0 + i, CalculateOffset(info.GetAxis(i), stick.Details.Min[i], stick.Details.Max[i])); } for (int i = 0; i < stick.Details.Capabilities.ButtonCount; i++) { state.SetButton(JoystickButton.Button0 + i, (info.Buttons & 1 << i) != 0); } state.SetIsConnected(true); } else if (result == JoystickError.Unplugged) { UnplugJoystick(player_index); } } else { // Use joyGetPosEx JoyInfoEx info = new JoyInfoEx(); info.Size = JoyInfoEx.SizeInBytes; info.Flags = JoystickFlags.All; JoystickError result = UnsafeNativeMethods.joyGetPosEx(device_index, ref info); if (result == JoystickError.NoError) { for (int i = 0; i < stick.Details.Capabilities.AxisCount; i++) { state.SetAxis(JoystickAxis.Axis0 + i, CalculateOffset(info.GetAxis(i), stick.Details.Min[i], stick.Details.Max[i])); } for (int i = 0; i < stick.Details.Capabilities.ButtonCount; i++) { state.SetButton(JoystickButton.Button0 + i, (info.Buttons & 1 << i) != 0); } state.SetIsConnected(true); } else if (result == JoystickError.Unplugged) { UnplugJoystick(player_index); } } } return(state); } }
JoystickDevice <WinMMJoyDetails> OpenJoystick(int number) { lock (sync) { JoystickDevice <WinMMJoyDetails> stick = null; JoyCaps caps; JoystickError result = UnsafeNativeMethods.joyGetDevCaps(number, out caps, JoyCaps.SizeInBytes); if (result == JoystickError.NoError) { if (caps.NumAxes > JoystickState.MaxAxes) { Debug.Print("[Input] Device has {0} axes, which is higher than OpenTK maximum {1}. Please report a bug at http://www.opentk.com", caps.NumAxes, JoystickState.MaxAxes); caps.NumAxes = JoystickState.MaxAxes; } if (caps.NumAxes > JoystickState.MaxButtons) { Debug.Print("[Input] Device has {0} buttons, which is higher than OpenTK maximum {1}. Please report a bug at http://www.opentk.com", caps.NumButtons, JoystickState.MaxButtons); caps.NumButtons = JoystickState.MaxButtons; } JoystickCapabilities joycaps = new JoystickCapabilities( caps.NumAxes, caps.NumButtons, (caps.Capabilities & JoystCapsFlags.HasPov) != 0 ? 1 : 0, true); int num_axes = caps.NumAxes; if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0) { num_axes += 2; } stick = new JoystickDevice <WinMMJoyDetails>(number, num_axes, caps.NumButtons); stick.Details = new WinMMJoyDetails(joycaps); // Make sure to reverse the vertical axes, so that +1 points up and -1 points down. for (int axis = 0; axis < caps.NumAxes; axis++) { stick.Details.Min[axis] = caps.GetMin(axis); stick.Details.Max[axis] = caps.GetMax(axis); } if ((caps.Capabilities & JoystCapsFlags.HasPov) != 0) { stick.Details.PovType = PovType.Exists; if ((caps.Capabilities & JoystCapsFlags.HasPov4Dir) != 0) { stick.Details.PovType |= PovType.Discrete; } if ((caps.Capabilities & JoystCapsFlags.HasPovContinuous) != 0) { stick.Details.PovType |= PovType.Continuous; } } // Todo: Implement joystick name detection for WinMM. stick.Description = String.Format("Joystick/Joystick #{0} ({1} axes, {2} buttons)", number, stick.Axis.Count, stick.Button.Count); // Todo: Try to get the device name from the registry. Oh joy! //string key_path = String.Format("{0}\\{1}\\{2}", RegistryJoyConfig, caps.RegKey, RegstryJoyCurrent); //RegistryKey key = Registry.LocalMachine.OpenSubKey(key_path, false); //if (key == null) // key = Registry.CurrentUser.OpenSubKey(key_path, false); //if (key == null) // stick.Description = String.Format("USB Joystick {0} ({1} axes, {2} buttons)", number, stick.Axis.Count, stick.Button.Count); //else //{ // key.Close(); //} Debug.Print("Found joystick on device number {0}", number); index_to_stick.Add(number, sticks.Count); player_to_index.Add(player_to_index.Count, number); sticks.Add(stick); } return(stick); } }
public JoystickState GetState(int player_index) { lock (sync) { JoystickState state = new JoystickState(); if (IsValid(player_index)) { int device_index = player_to_index[player_index]; int index = index_to_stick[device_index]; JoystickDevice <WinMMJoyDetails> stick = sticks[index] as JoystickDevice <WinMMJoyDetails>; // For joysticks with fewer than three axes or four buttons, we must // use joyGetPos; otherwise, joyGetPosEx. This is not just a cosmetic // difference, simple devices will return incorrect results if we use // joyGetPosEx on them. if (stick.Details.Capabilities.AxisCount <= 3 || stick.Details.Capabilities.ButtonCount <= 4) { // Use joyGetPos JoyInfo info = new JoyInfo(); JoystickError result = UnsafeNativeMethods.joyGetPos(device_index, ref info); if (result == JoystickError.NoError) { for (int i = 0; i < stick.Details.Capabilities.AxisCount; i++) { state.SetAxis(JoystickAxis.Axis0 + i, CalculateOffset(info.GetAxis(i), stick.Details.Min[i], stick.Details.Max[i])); } for (int i = 0; i < stick.Details.Capabilities.ButtonCount; i++) { state.SetButton(JoystickButton.Button0 + i, (info.Buttons & 1 << i) != 0); } state.SetIsConnected(true); } else if (result == JoystickError.Unplugged) { UnplugJoystick(player_index); } } else { // Use joyGetPosEx JoyInfoEx info_ex = new JoyInfoEx(); info_ex.Size = JoyInfoEx.SizeInBytes; info_ex.Flags = JoystickFlags.All; JoystickError result = UnsafeNativeMethods.joyGetPosEx(device_index, ref info_ex); if (result == JoystickError.NoError) { for (int i = 0; i < stick.Details.Capabilities.AxisCount; i++) { state.SetAxis(JoystickAxis.Axis0 + i, CalculateOffset(info_ex.GetAxis(i), stick.Details.Min[i], stick.Details.Max[i])); } for (int i = 0; i < stick.Details.Capabilities.ButtonCount; i++) { state.SetButton(JoystickButton.Button0 + i, (info_ex.Buttons & 1 << i) != 0); } for (int i = 0; i < stick.Details.Capabilities.HatCount; i++) { // A discrete POV returns specific values for left, right, etc. // A continuous POV returns an integer indicating an angle in degrees * 100, e.g. 18000 == 180.00 degrees. // The vast majority of joysticks have discrete POVs, so we'll treat all of them as discrete for simplicity. if ((JoystickPovPosition)info_ex.Pov != JoystickPovPosition.Centered) { HatPosition hatpos = HatPosition.Centered; if (info_ex.Pov < 4500 || info_ex.Pov >= 31500) { hatpos |= HatPosition.Up; } if (info_ex.Pov >= 4500 && info_ex.Pov < 13500) { hatpos |= HatPosition.Right; } if (info_ex.Pov >= 13500 && info_ex.Pov < 22500) { hatpos |= HatPosition.Down; } if (info_ex.Pov >= 22500 && info_ex.Pov < 31500) { hatpos |= HatPosition.Left; } state.SetHat(JoystickHat.Hat0 + i, new JoystickHatState(hatpos)); } } state.SetIsConnected(true); } else if (result == JoystickError.Unplugged) { UnplugJoystick(player_index); } } } return(state); } }